Быстро IEnumerable в массив
От: Glas  
Дата: 12.05.13 15:14
Оценка:
Подскажи самый быстрый способ преобразования IEnumerable в массив.

На входе подается массив длинной несколько сотен миллионов значений. Нужно очищать этот массив от мусора в зависимости от текущей итерации. И есть библиотека, которая знает только о массивах.
Самое быстрое, что я смог придумать выглядит вот так.
ushort[] curBuffer = new ushort[size];//size - размер массива
for (int k = 0; k < size; k++)
     curBuffer[k] = (ushort)(_buffer[k] == (iterationNumber + 1) ? 1 : 0);//_buffer - входной массив

Это оказалось на пару секунд быстрей, чем метод ToArray().
Может, еще быстрее как-то можно?

Для тех у кого возникнут вопросы, что на входе и выходе:
Вход: 1 1 1 0 0 0 2 2 2 ... N N N
На выходе на первой итерации: 1 1 1 0 0 0 0 0 0 ... 0 0 0
На выходе на второй итерации: 0 0 0 0 0 0 2 2 2 ... 0 0 0 и тд
Re: Быстро IEnumerable в массив
От: Аноним  
Дата: 12.05.13 15:44
Оценка:
Здравствуйте, Glas, Вы писали:

G>Подскажи самый быстрый способ преобразования IEnumerable в массив.


G>На входе подается массив длинной несколько сотен миллионов значений. Нужно очищать этот массив от мусора в зависимости от текущей итерации. И есть библиотека, которая знает только о массивах.

G>Самое быстрое, что я смог придумать выглядит вот так.
G>
G>ushort[] curBuffer = new ushort[size];//size - размер массива
G>for (int k = 0; k < size; k++)
G>     curBuffer[k] = (ushort)(_buffer[k] == (iterationNumber + 1) ? 1 : 0);//_buffer - входной массив
G>

G>Это оказалось на пару секунд быстрей, чем метод ToArray().
G>Может, еще быстрее как-то можно?

G>Для тех у кого возникнут вопросы, что на входе и выходе:

G>Вход: 1 1 1 0 0 0 2 2 2 ... N N N
G>На выходе на первой итерации: 1 1 1 0 0 0 0 0 0 ... 0 0 0
G>На выходе на второй итерации: 0 0 0 0 0 0 2 2 2 ... 0 0 0 и тдъ

Откуда сотня миллионов такая идет ?
Re[2]: Быстро IEnumerable в массив
От: Glas  
Дата: 12.05.13 17:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Откуда сотня миллионов такая идет ?


Трехмерное изображение.
Re[3]: Быстро IEnumerable в массив
От: Аноним  
Дата: 12.05.13 17:11
Оценка:
Здравствуйте, Glas, Вы писали:

G>Здравствуйте, Аноним, Вы писали:


А>>Откуда сотня миллионов такая идет ?


G>Трехмерное изображение.


C устройства камеры или с файловой системы, по сети загружается ? Сколько времени занимает прием входных данных ?
Re: Быстро IEnumerable в массив
От: Lloyd Россия  
Дата: 12.05.13 17:12
Оценка:
Здравствуйте, Glas, Вы писали:

G>На входе подается массив длинной несколько сотен миллионов значений. Нужно очищать этот массив от мусора в зависимости от текущей итерации. И есть библиотека, которая знает только о массивах.

G>Самое быстрое, что я смог придумать выглядит вот так.
G>...
G>Это оказалось на пару секунд быстрей, чем метод ToArray().
G>Может, еще быстрее как-то можно?

Имхо, хороший кандидат на распаралеливание. Несколько сотен миллионов элементов — это довольно-таки значительные цифры.
Re[4]: Быстро IEnumerable в массив
От: Glas  
Дата: 12.05.13 18:12
Оценка:
Здравствуйте, Аноним, Вы писали:

А>C устройства камеры или с файловой системы, по сети загружается ? Сколько времени занимает прием входных данных ?


Зачем это все? Я четко обозначил узкое место. Входной массив я изменить не могу.
Re[2]: Быстро IEnumerable в массив
От: Glas  
Дата: 12.05.13 18:16
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Имхо, хороший кандидат на распаралеливание. Несколько сотен миллионов элементов — это довольно-таки значительные цифры.


Запихал итерации в потоки по количеству ядер, но боюсь как бы не словить OutOfMemory. Из 6с на всю итерацию, 4 тратится на копию буфера
Re: Быстро IEnumerable в массив
От: Glas  
Дата: 12.05.13 18:28
Оценка:
Сократил до 2с через
for (int k = 0; k < size; k++)
{
    bool value = _buffer[k] == (iterationNumber + 1);
    if (value)
        curListVolBuffer[k] = 1;
}

По идее убрал лишние операции присваивания.
Re[2]: Быстро IEnumerable в массив
От: Аноним  
Дата: 12.05.13 19:35
Оценка:
Здравствуйте, Glas, Вы писали:


for (int k = 0; k < size; k++)


Хорошо бы еще size заменить на curListVolBuffer.Length, чтобы избавиться от проверки на IndexOutOfRange.

ps: не очень понятно причем тут IEnumerable
Re[3]: Быстро IEnumerable в массив
От: Lloyd Россия  
Дата: 12.05.13 21:49
Оценка:
Здравствуйте, Glas, Вы писали:

L>>Имхо, хороший кандидат на распаралеливание. Несколько сотен миллионов элементов — это довольно-таки значительные цифры.


G>Запихал итерации в потоки по количеству ядер, но боюсь как бы не словить OutOfMemory.


Не понятно, что вы имеете в виду. Можно привести пример кода?
Re[5]: Быстро IEnumerable в массив
От: Аноним  
Дата: 12.05.13 22:11
Оценка:
Здравствуйте, Glas, Вы писали:

G>Здравствуйте, Аноним, Вы писали:


А>>C устройства камеры или с файловой системы, по сети загружается ? Сколько времени занимает прием входных данных ?


G>Зачем это все? Я четко обозначил узкое место. Входной массив я изменить не могу.


Тем что 100 Мб мгновенно не появляются из неоткуда, можно обрабатывать данные по мере их считывания.
Re[2]: Быстро IEnumerable в массив
От: Uzzy Россия  
Дата: 13.05.13 03:29
Оценка:
Здравствуйте, Glas, Вы писали:

G>Сократил до 2с через

G>
G>for (int k = 0; k < size; k++)
G>{
G>    bool value = _buffer[k] == (iterationNumber + 1);
G>    if (value)
G>        curListVolBuffer[k] = 1;
G>}
G>

G>По идее убрал лишние операции присваивания.

Компилятор оптимизирует выделенное или операция сложения будет выполняться 100 миллионов раз?
Re[3]: Быстро IEnumerable в массив
От: Glas  
Дата: 13.05.13 06:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Хорошо бы еще size заменить на curListVolBuffer.Length, чтобы избавиться от проверки на IndexOutOfRange.


size и Length одинаковы, или тут у меня какой-то пробел в знании?

А>ps: не очень понятно причем тут IEnumerable


сперва делал
_buffer.Select(val => val == (iteration + 1) ? 1 : 0)).ToArray()
Re[3]: Быстро IEnumerable в массив
От: Glas  
Дата: 13.05.13 06:07
Оценка:
Здравствуйте, Uzzy, Вы писали:

U>Компилятор оптимизирует выделенное или операция сложения будет выполняться 100 миллионов раз?


Ага, спасибо, слона то и не приметил.
Re[4]: Быстро IEnumerable в массив
От: Glas  
Дата: 13.05.13 06:13
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Не понятно, что вы имеете в виду. Можно привести пример кода?

for (int i = 0; i < iteration;)
            {
                List<Thread> threads = new List<Thread>();
                for (int j = 0; j < Environment.ProcessorCount; j++)
                {
                    Thread thread = new Thread(() => CreateThread(i++));//в CreateThread() цикл который описан выше.
                    thread.Start();

                    threads.Add(thread);
                }

                while (threads.Where(val => val.ThreadState == ThreadState.Running).Any()) { }
            }

На х32 при трех потоках OutOfMemory выскакивает. В х64 вроде все ок, но все равно страшно
Re[4]: Быстро IEnumerable в массив
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.05.13 04:09
Оценка:
Здравствуйте, Glas, Вы писали:

G>size и Length одинаковы, или тут у меня какой-то пробел в знании?

Подробность реализации JIT-оптимизатора CLR (она ещё и зависит от x86/x64). Проверьте.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.