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

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

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

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
По умолчанию Заблуждения в оптимизации

Создал эту тему просто, чтобы поделиться опытом своих заблуждений)

Несколько раз читал разные блоги и сайты по оптимизации приложений, и последний раз читал статью Дэниэла по оптимизации кода в старлинге.
Сам код для потимизации stage3d оставлю, меня заинтересовало то, что он рекомендовал избегать использования for each циклов, и заменять их на for var i:int ...
Но мои замеры показали, что разница в скорости между этими циклами составляет почти 3 раза! Причем совсем не в пользу вторых.

Тест содержит ошибку, ответ здесь
Вот мой тест на 10 миллионах объектов
Код AS3:
// создаем 10 миллионов объектов с одним свойством
var array:Array = []
for (var i:int = 0; i < 10000000; i++) {
	array.push( { t: 1 } );
}
 
var length:int = array.length;
var obj:Object = null;
var time:int = getTimer();
for (i = 0; i < length; i++) {
	obj = array[i];
	obj.t = 0;
}
trace("FOR i", getTimer() - time); // 1554
time = getTimer();
for each (obj in array) {
	obj.t = 0;
}
trace("FOR EACH", getTimer() - time); // 671
Но если тут я сам и ожидал примерно такого результата, то вот хорошей скорости работы от Math методов точно не ожидал. А оказалось, что они лишь немного проигрывают в скорости инлайнам. И ощутимо это только на огромном количестве итераций.
Вот еще пример
Код AS3:
public function MathCrap() {
 
 
	var number:Number = -14;
	var i:int = 0;
	var result:Number = 0;
	var time:int = 0;
 
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = Math.abs(number);
	}
	trace("Math.abs()", getTimer() - time); 
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = abs(number);
	}
	trace("Inline abs", getTimer() - time);
	trace("CEIL >>>");
	number = 1.5;
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = Math.ceil(number);
	}
	trace("Math.ceil()", getTimer() - time); 
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = ceil(number);
	}
	trace("Inline ceil", getTimer() - time);
 
}
[Inline]
public static function abs(value:Number):Number {
	return value > 0 ? value : -value;
}
[Inline]
public static function ceil(value:Number):int {
	return int(value) + 1;
}
Результат такой:
Код AS3:
Math.abs() 1328
Inline abs 1139
CEIL >>>
Math.ceil() 1348
Inline ceil 1139
То есть совсем незначительная разница, хотя я расчитывал увидеть цифры раза в 2, а то и в 3 различающиеся. Видимо Адоби хорошо поработали над оптимизацией кода в ASC 2.0
__________________
Ко мне можно и нужно обращаться на ты)


Последний раз редактировалось caseyryan; 26.02.2016 в 09:15.
Старый 24.02.2016, 11:27
Korchy вне форума Посмотреть профиль Отправить личное сообщение для Korchy Найти все сообщения от Korchy
  № 2  
Ответить с цитированием
Korchy
 
Аватар для Korchy

Регистрация: May 2011
Сообщений: 301
Записей в блоге: 2
Цитата:
Сообщение от caseyryan Посмотреть сообщение
он рекомендовал избегать использования for each циклов, и заменять их на for var i:int ...
Обычно each-циклы не рекомендуют использовать из-за того, что не гарантируется порядок обхода. А по скорости ни разу не встречал таких рекомендаций.
__________________
interplanety

Старый 24.02.2016, 11:30
i.o. вне форума Посмотреть профиль Отправить личное сообщение для i.o. Найти все сообщения от i.o.
  № 3  
Ответить с цитированием
i.o.
 
Аватар для i.o.

Регистрация: Apr 2010
Адрес: Earth
Сообщений: 1,897
Результаты в DEBUG и RELEASE версиях плеера могут сильно отличаться. Судя по трейсам использовался именно дебажный вариант

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

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Да, и ещё версию тестов с старым компилятором бы.
__________________
Дети не должны знать о своих родителях

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

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Обычно each-циклы не рекомендуют использовать из-за того, что не гарантируется порядок обхода. А по скорости ни разу не встречал таких рекомендаций.
Да. Но он там говорил именно о скорости работы, поэтому меня это и заинтересовало. Так как я всегда был уверен что for in и for each in гораздо быстрее упорядоченных циклов
Вот цитата Дэниэла
Цитата:
Loops

When working with loops that are repeated very often or are deeply nested, it's better to avoid “for each”; the classic “for i” yields a better performance. Furthermore, beware that the loop condition is executed once per loop, so it's faster to save it into an extra variable.
Цитата:
Сообщение от i.o. Посмотреть сообщение
Результаты в DEBUG и RELEASE версиях плеера могут сильно отличаться. Судя по трейсам использовался именно дебажный вариант
Блин, а ведь верно. Я даже не подумал) Туплю.
Сделал релизный тест, и мои изначальные ожидания оправдались с лихвой.
Вот для релиза:

Код AS3:
public function MathCrap() {
 
	var tf:TextField = new TextField();
	tf.width = 800;
	tf.height = 600;
	addChild(tf);
 
	var number:Number = -14;
	var i:int = 0;
	var result:Number = 0;
	var time:int = 0;
 
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = Math.abs(number);
	}
	tf.appendText("Math.abs() " + (getTimer() - time) + "\n"); 
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = abs(number);
	}
	tf.appendText("Inline abs " + (getTimer() - time) + "\n");
	tf.appendText("CEIL >>>");
	number = 1.5;
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = Math.ceil(number);
	}
	tf.appendText("Math.ceil() " + (getTimer() - time) + "\n");
	time = getTimer();
	for (i = 0; i < 10000000; i++) {
		result = ceil(number);
	}
	tf.appendText("Inline ceil " + (getTimer() - time) + "\n");
 
}
[Inline]
public static function abs(value:Number):Number {
	return value > 0 ? value : -value;
}
[Inline]
public static function ceil(value:Number):int {
	return int(value) + 1;
}
Код AS3:
Math.abs() 528
Inline abs 85
CEIL >>>Math.ceil() 549
Inline ceil 55
То то же

Никогда не думал, что придется настолько заморачиваться с оптимизацией приложений)
__________________
Ко мне можно и нужно обращаться на ты)

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

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Цитата:
Math.abs() 528
Inline abs 85
Да ну нафиг, в 6 раз что ли разница?
А вот с ceil при приведений Number к int мы можем потерять информацию, если число будет за диапазоном int. Мы так-же потеряем Infinity и NaN в обоих случаях.

И ещё, неужели весь остальной код в игре уже так идеально оптимизирован, что пришлось взяться за нативные реализаций?
__________________
Дети не должны знать о своих родителях

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

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
А вот с ceil при приведений Number к int мы можем потерять информацию, если число будет за диапазоном int. Мы так-же потеряем Infinity и NaN в обоих случаях.
Да, ты прав, надо как-то bitwise видимо задействовать.

Цитата:
И ещё, неужели весь остальной код в игре уже так идеально оптимизирован, что пришлось взяться за нативные реализаций?
Видимо да. Оптимизирую те места, где скаут показывает наибольшие потери в производительности. Уже давно оптимизирую все что только можно. И больше всего погряз в Dragon Bones. Там огромные просторы для оптимизации Made in China говорит само за себя)
__________________
Ко мне можно и нужно обращаться на ты)

Старый 24.02.2016, 12:00
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 8  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Если получиться ускорить ceil, round с поддержкой Number, ты обязательно напиши.

Цитата:
Made in China
Да там ребята вообще огонь!

Ещё вот о чём я думал, так как класс Math. нативный, он может быть по разному реализован на разных архитектурах процессоров. Где-то быстрее, где то медленнее. В то время как собственная, кастомная реализация везде будет одинаковой по скорости. Я к тому, что было бы здорово, после написания теста, прогнать его на разных устройствах, в том числе web player конечно! )
__________________
Дети не должны знать о своих родителях

Старый 24.02.2016, 12:19
undefined вне форума Посмотреть профиль Отправить личное сообщение для undefined Найти все сообщения от undefined
  № 9  
Ответить с цитированием
undefined

Регистрация: Oct 2006
Сообщений: 2,281
Цитата:
Сделал релизный тест, и мои изначальные ожидания оправдались с лихвой.
Так а что для циклов в релизе?

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

Регистрация: Apr 2010
Адрес: Earth
Сообщений: 1,897
Вычисление целой и дробной части не на интах будет примерно таким
Код AS3:
var n:Number = 100000 * (0.5 - Math.random());
 
var frac:Number = n % 1;
var full:Number = n - frac;
Для round() floor() и ceil() можно допереть)

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

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

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


 


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


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