Показать сообщение отдельно
Старый 17.12.2014, 13:02   #13
Жека
Дэвелопер
 
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений
(для 886 пользователей)
Ответ: Смесь: Неочевидное + Оптимизация

Копирование массивов, System.arrayCopy()

Чудесный и шустрый метод для копирования данных из одного массива в другой, как целиком, так и части.

У себя в коде использую

* при расширении массивов, создаём массив большего размера, копируем в него текущий массив (надо бы избавиться от этих expand'ов)

* при чтении байтов из сокета

Чтение из сокета:

Читаем из сокета байты в фиксированный буфер, выцепляем команды. Всё бы хорошо, но данные идут сплошным потоком, т.е. буфер может быть заполнен полностью, и при этом его окончание - это лишь часть от команды, чтобы вытащить команду, нужно догрузить оставшуюся часть.

С давних пор у меня делался сдвиг содержимого этого буфера от последней неполной команды в начало буфера:
for(int k = lastPos; k < size; ++k) {
    buf[k-lastPos] = buf[k];
}

//size = 2048 байт
//lastPos - позиция неполной команды
Сравнил скорость присвоения в цикле и arrayCopy, копирование побеждает.

Оговорка: я копирую часть массива в тот же самый массив.
В доке сказано, что если копируемые области совпадут, то будет создан промежуточный массив.
Количество наложений областей копирования я не замерял, в теории должно быть редко, т.к. средняя длина команд заметно меньше размера буфера.

Есть мысль вообще не сдвигать байты, замутить циклическое заполнение массива. В прошлый раз не сообразил как это удобно сделать.
А ещё - при выцеплении команды нужно будет копировать два куска данных - начало команды с конца буфера и её продолжение с начала буфера.

Официальное описание функции arrayCopy() (english).
(Offline)
 
Ответить с цитированием