|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
БАГ или УТЕЧКА памяти в слиянии массивов!?
Обнаружил кое-что странное, не знаю точно является ли это багом или утечкой памяти, а может быть это вообще нормальная работа флеш плеера...
Суть в следующем: есть у меня в игре парсер 3д моделей, так вот, для слияния двух массивов с данными я использовал функцию concat и всё бы ничего, пока я не решил загрузить очень тяжелую модель. И заметил, что парсинг идет не плавно, как это должно быть, а постепенно замедляется. Исследовав код парсера обнаружил, что всё дело в функции concat, которая объединяет данные из нескольких массивов в один. Для теста сделал следующее: var t:int = getTimer(); var a:Array = new Array(); var b:Array = [1, 2, 3, 4, 5]; for (var i:int = 0; i < 250000; i++) { a = a.concat(b); // Вываливается с ошибкой, что скрипт слишком долго выполняется } trace(getTimer() - t + "ms"); for (i = 0; i < 250000; i++) { for (var k:int = 0; k < b.length; k++) a.push(b[k]); // Здесь всё нормально, 250 ms } trace(getTimer() - t + "ms"); for (i = 0; i < 250000; i++) { for (var k:int = 0; k < b.length; k++) a[a.length] = b[k]; // Здесь всё нормально, 227 ms } trace(getTimer() - t + "ms"); Сейчас решил проверить свою гипотезу, сделал функцию аналогичную concat: var t:int = getTimer(); var a:Array = new Array(); var b:Array = [1, 2, 3, 4, 5]; for (var i:int = 0; i < 250000; i++) { a = myConcat(a, b); // Вывалилось с ошибкой. } trace(getTimer() - t + "ms"); private function myConcat(m:Array, ...rest):Array { var a:Array = new Array(); for (var i:int = 0; i < m.length; i++) a.push(m[i]); for (i = 0; i < rest.length; i++) { for (var j:int = 0; j < rest[i].length; j++) a.push(rest[i][j]); } return a; } Всё нормально.
__________________
Я заклинаю вас действовать иначе. Последний раз редактировалось Bletraut; 07.05.2016 в 14:11. |
|
|||||
Регистрация: Apr 2009
Сообщений: 409
|
Если я все правильно понял из вопроса, то в доке и сказано что concat создает новый массив на основе двух, а array.concat() без аргументов создает клон массива. так что в вашем случае лучше использовать myConcat, но быстрее будет без пуша. еще можно попробовать объеденить сплайсом, но тут не уверен.
по идее должно выглядеть так, не понял зачем второй цикл |
|
|||||
Нет, я уже понял где затупил. В общем флеш не умеет быстро клонировать массивы, поэтому при "клонировании" она переносит все ссылки на объекты из одного массива в другой. В результате этого ей приходится делать двойной перебор, следовательно, слияние двух огромных массивов с данными лучше так не делать.
Аналог функции myConcat, я в начале неправильно написал, поэтому всё и работало. Исправил. Slice не намного быстрее, чем concat
__________________
Я заклинаю вас действовать иначе. |
|
|||||
Регистрация: Apr 2009
Сообщений: 409
|
врядли в других языках это работает как иначе, если не нужно менять два исходных объекта, то только полый перенос ссылок в третий, в варианте с цифрами/строками копируются кстати не ссылки, а значения)
|
|
|||||
Цитата:
Добавлено через 49 секунд Да я бы это и не заметил никогда, пока бы гигантские модели не стал грузить.
__________________
Я заклинаю вас действовать иначе. |
Часовой пояс GMT +4, время: 10:28. |
|
« Предыдущая тема | Следующая тема » |
Теги |
адолбы , баг , ошибка , тупость |
|
|