Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 07.05.2016, 02:10
Bletraut вне форума Посмотреть профиль Отправить личное сообщение для Bletraut Найти все сообщения от Bletraut
  № 1  
Ответить с цитированием
Bletraut
 
Аватар для Bletraut

Регистрация: Mar 2013
Адрес: Вне пространства.
Сообщений: 566
Отправить сообщение для Bletraut с помощью ICQ Отправить сообщение для Bletraut с помощью Skype™
Attention БАГ или УТЕЧКА памяти в слиянии массивов!?

Обнаружил кое-что странное, не знаю точно является ли это багом или утечкой памяти, а может быть это вообще нормальная работа флеш плеера...
Суть в следующем: есть у меня в игре парсер 3д моделей, так вот, для слияния двух массивов с данными я использовал функцию concat и всё бы ничего, пока я не решил загрузить очень тяжелую модель. И заметил, что парсинг идет не плавно, как это должно быть, а постепенно замедляется. Исследовав код парсера обнаружил, что всё дело в функции concat, которая объединяет данные из нескольких массивов в один.

Для теста сделал следующее:

Код AS3:
 
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, но есть предположение, что при каждом вызове метода, создается новый экземпляр массива и сборщик мусора не успевает очищать память, тем самым появляются лаги. Прав я или нет? Стоит ли писать адобу в поддержку или же это нормальное явление?

Сейчас решил проверить свою гипотезу, сделал функцию аналогичную concat:
Код AS3:
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;
}
Получается, что concat это самый настоящий баг???

Всё нормально.
__________________
Я заклинаю вас действовать иначе.


Последний раз редактировалось Bletraut; 07.05.2016 в 14:11.
Старый 07.05.2016, 14:02
faraday вне форума Посмотреть профиль Отправить личное сообщение для faraday Найти все сообщения от faraday
  № 2  
Ответить с цитированием
faraday
 
Аватар для faraday

Регистрация: Apr 2009
Сообщений: 409
Если я все правильно понял из вопроса, то в доке и сказано что concat создает новый массив на основе двух, а array.concat() без аргументов создает клон массива. так что в вашем случае лучше использовать myConcat, но быстрее будет без пуша. еще можно попробовать объеденить сплайсом, но тут не уверен.
по идее должно выглядеть так, не понял зачем второй цикл
Код AS3:
private function myConcat(a:Array, b:Array):Array
{
	var l:uint=a.length;	
	for (var i:int = 0; i < b.length; i++)
           a[l+i]=b[i];
	return a;
}

Старый 07.05.2016, 14:10
Bletraut вне форума Посмотреть профиль Отправить личное сообщение для Bletraut Найти все сообщения от Bletraut
  № 3  
Ответить с цитированием
Bletraut
 
Аватар для Bletraut

Регистрация: Mar 2013
Адрес: Вне пространства.
Сообщений: 566
Отправить сообщение для Bletraut с помощью ICQ Отправить сообщение для Bletraut с помощью Skype™
Нет, я уже понял где затупил. В общем флеш не умеет быстро клонировать массивы, поэтому при "клонировании" она переносит все ссылки на объекты из одного массива в другой. В результате этого ей приходится делать двойной перебор, следовательно, слияние двух огромных массивов с данными лучше так не делать.

Аналог функции myConcat, я в начале неправильно написал, поэтому всё и работало. Исправил.
Slice не намного быстрее, чем concat
__________________
Я заклинаю вас действовать иначе.

Старый 07.05.2016, 14:16
faraday вне форума Посмотреть профиль Отправить личное сообщение для faraday Найти все сообщения от faraday
  № 4  
Ответить с цитированием
faraday
 
Аватар для faraday

Регистрация: Apr 2009
Сообщений: 409
врядли в других языках это работает как иначе, если не нужно менять два исходных объекта, то только полый перенос ссылок в третий, в варианте с цифрами/строками копируются кстати не ссылки, а значения)

Старый 07.05.2016, 14:24
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 5  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
А где реально может потребоваться такое количество слияний массивов? Для чего вообще?
__________________
Ко мне можно и нужно обращаться на ты)

Старый 07.05.2016, 23:10
Bletraut вне форума Посмотреть профиль Отправить личное сообщение для Bletraut Найти все сообщения от Bletraut
  № 6  
Ответить с цитированием
Bletraut
 
Аватар для Bletraut

Регистрация: Mar 2013
Адрес: Вне пространства.
Сообщений: 566
Отправить сообщение для Bletraut с помощью ICQ Отправить сообщение для Bletraut с помощью Skype™
Цитата:
Сообщение от caseyryan Посмотреть сообщение
А где реально может потребоваться такое количество слияний массивов? Для чего вообще?
Создание чанка.

Добавлено через 49 секунд
Да я бы это и не заметил никогда, пока бы гигантские модели не стал грузить.
__________________
Я заклинаю вас действовать иначе.

Старый 09.05.2016, 13:03
dimarik вне форума Посмотреть профиль Отправить личное сообщение для dimarik Найти все сообщения от dimarik
  № 7  
Ответить с цитированием
dimarik
.
 
Аватар для dimarik

модератор форума
Регистрация: Sep 2003
Адрес: Москва
Сообщений: 4,630
Записей в блоге: 20
Угу. Иногда и сортировку лучше сделать ручками.
__________________
Воспитан в TimeZero. Работаю в Mail.ru.

Создать новую тему Ответ Часовой пояс GMT +4, время: 20:27.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Теги
адолбы , баг , ошибка , тупость
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 20:27.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.