![]() |
Оптимизация: int vs uint, i+=1 vs i++ и т.д.
Провёл небольшое исследование.
1. Что лучше: int или uint, и почему вообще между ними есть разница. 2. Что лучше: i+=1 или i++. Исследование проводилось следующим образом. Нижеописанный класс был откомпилирован с помощью командного компилятора из Flex SDK (надо отметить, что компилятор Flash CS3 выдаёт те же результаты). Затем полученный .swf был декомпилирован с помощью abcdump из проекта Tamarin. Код:
package {Вот так выглядит присвоение x = 0: Поле int: Код:
findproperty private::aКод:
findproperty private::bКод:
pushbyte 0Код:
pushbyte 0Поле int: Код:
findpropstrict private::aКод:
findpropstrict private::bКод:
inclocal_i 1Код:
getlocal1 Поле int: Код:
findproperty private::aКод:
findproperty private::bКод:
getlocal1 Код:
getlocal1 Выводы: 1. Для полей нет разницы между int и uint (кроме области допустимых значений, разумеется). 2. При работе с локальными переменными типа uint часто используется инструкция конвертации convert_u, которая хоть и не значительно, но тем не менее может снизить произодительность. convert_i тоже иногда используется, но реже. 3. При работе с полями объекта выражение i+=1 компилируется в гораздо меньшее количество инструкций, чем i++ и выполняется значительно быстрее. 4. Наиболее быстрым выражением является i++ если i - это локальная переменная типа int. В этом случае выражение компилируется всего в одну инструкцию AVM2. Если i типа uint, то получается уже 4 инструкции. |
Занятненько...
Спасибо. |
Спасибо.
А я давно подозревал и везде использовал int вместо uint. uint только в константах. |
Не забывайте, что это разница в скорости актуальна при использовании полей класса, а не локальных переменных.
|
выигрыш/проигрыш производительности составляет настолько мизерную разницу, что я не могу привести реальный пример, где бы это сыграло хоть малейшую роль.
|
Спасибо. Интересно. На буржуйском сайте тайминг проводили - самый быстрый цикл выглядел следующим образом:
Код:
var i:int; |
Конечно, всё ещё во многом зависит от того, как байт-код будет переведён в нативнй код jit-компилятором.
Однако, здравый смысл подсказывает, что Код:
inclocal_i 1Код:
getlocal1 А колупать исходники AVM2 как-то не очень хочется :) |
Использовался Flex Builder 3 ?
|
Из классики:
На первом этапе программирования нужно сосредоточиться на правильной архитектуре приложения, читабельности кода, прозрачности и правильности логики. Только после окончания создания приложения следует протестировать производительность приложения, и только затем, на основании конкретных результатов тестов производить пошаговую оптимизацию, каждый раз обращая внимание на самые проблемные места кода. К чему это я свои 5 копеек в этот флейм тащу: Производительность конкретного кода цикла здесь обсуждается не в рамках единого процесса оптимизации, а как отдельная фишка. Боюсь, что знание методологии оптимизации кода в данном топике подменяется на следование ничему не значащим фактам. Почему не значащим? Потому, что один лишний вызов метода съест с лихвой всю экономию на всех циклах за всё время работы приложения. Не питайте иллюзий, что сабж вам поможет писать быстрые приложения. ИМХО |
Цитата:
Использовался консольный компилятор из Flex 2 SDK. Кстати, хорошая идея! Надо проверить, в Flex 3 SDK, может быть что-то изменилось. Цитата:
Тем не менее, для того, чтобы оптимизировать, необходимо знать как влияют на быстродействие те или иные операции. Например, то, что вызов методов в AS3 происходит крайне медленно - это ведь тоже не с потолка взято, а опять же было проверено экспериментально. И, скажем, тот факт, что в AS1/AS2 использование x & 1 вместо x % 2 не давало никакого выигрыша, тоже кто-то когда-то проверил. Это я к тому, что методология методологией, но без знания быстродействия конкретных элементарных операций будет вообще непонятно КАК оптимизировать (за исключением оптимизации алгоритма, разумеется). |
А можно подробнее про вызов метода?
|
Вот на этих страничках можно почитать про исследование быстродействия различных арифметических операций.
http://www.rockonflash.com/blog/?p=63 http://osflash.org/as3_speed_optimizations Было определено, что методы класса Math работают довольно медленно. На самом деле дело не в том, что методы какие-то тормознутые, а в том, что вообще происходит вызов метода. Например, вместо Math.abs(x) лучше использовать x<0?-x:x Но если кто-то решит создать класс с быстрой математикой, например такой: Код:
package {А всё дело в том, что сам вызов метода и возврат назад кушают больше, чем содержимое метода. |
Цитата:
|
Iv, так давайте поговорим о действительно значительных для производительности вещах :)
|
Вместо Math.floor можно спользовать: value >> 0; :)
Можно собрать список вот таких фич... :) Post Update: Протестил: Код:
var time:Number = 0;FloorTest: 2046 FloorUintTest: 392 FloorShiftTest: 280 |
Цитата:
Во-вторых, если в цикле идёт голая математика, а сам цикл достаточно длинный, то даже такие мелочи начинают иметь значение. В-третьих, иногда методы всё же вызываются, хотя мы этого и не предполагали. Вот, например, в чём разница между Код:
var a:int = int(n);Код:
var a:int = n;Разница в том, что в первом случае происходит вызов метода. Правда, что удивительно, на быстродействии это никак не сказывается. Так что в AVM2 всё очень даже неоднозначно. |
Цитата:
Знание и правильное применение хорошей практики, в частности, шаблонов проектирования. Как итог - понятный и логичный код без ошибок и лишних операций. Оптимизация кода - только как отдельный, завершающий и четко направленный на узкие места процесс, при наличии тестов. Прекращение оптимизации по достижении достаточной производительности. Примерно так. PS: На моей практике бывали случаи, когда приходилось брать чужой усосаный хаками для производительности код, переименовывать всё и вся, убирать хаки и т.п., после этого разбираться с логикой и делать тесты. Рекордный случай - удаление порядка 17 тысяч в кадр(!) лишних вызовов методов. Ни в одном из случаев процесс оптимизации не доходил до того, чтобы заменять циклы for на while или заменять типы данных или вызовы математических методов. Процесс оптимизации прекращался задолго до этого, на уровне изменения логики приложения. PPS: И да, не юзайте чужие хакерские приемы не проверив. И в этом топике в коде есть ошибки. Четко отдавайте себе отчет, готовы ли вы взамен на выигрыш в 0.0003 миллисекунды жертвовать читабельностью кода и риском внесения ошибки. |
WindWalker, согласен. Но тогда, наверное, не стоит подменять понятия и говорить именно о тонкостях внутренней механики, а не об оптимизации.
|
Цитата:
Просто сейчас всё идёт в сторону разрастания итак громоздкого кода ради его универсальности. Т.е. в итоге жертвуем производительностью в пользу удобства написания (прочтения, понимания, отладки, редактирования) кода. Эта позиция понятна: железо постоянно совершенствуется, поэтому теперь можно себе такое позволить. А почему бы не продолжать писать продуманный код, получая выигрыш в скорости при совершенствовании железа? Фреймворки и паттерны это удобно. Это и хорошо, ведь всё-таки их далеко не дураки придумывали. Тем не менее они все являются стандартизованными для общего случая. А общее решение, как известно, проигрывает решению, найденному для данной конкретной ситуации. Конечно для этого требуется более высокая квалификация кодера, но на то он и программер чтобы думать. Недостаточно просто выучить язык, нужно уметь правильно всё придумать и организовать. Сейчас программить становится всё легче и легче, соответственно растёт число быдлокодеров, которые пишут тормозной код, потому что его легче всего написать. Можно много ещё чего написать, вернуться к тому что я ни в коем случае не говорю что использовать паттерны это плохо итд, но я пожалуй пока остановлюсь. Ибо нахожусь немного в неадеквате :) С удовольствием выслушаю всё, что мне на это ответят |
GAIKER, я не вижу никакого противоречия.
Вот ты написал приложение, оно устраивает и тебя и заказчика по производительности. Будешь ли ты его оптимизировать? И, даже если будешь, то до какой степени? Нужна ли везде максимальная производительность? Как определить, что производительность уже максимальна и достигнут предел? Моя практика показывает, что вообще довольно редко доходим до этапа оптимизации кода. Но в том-то и дело, что оптимизация - отдельный этап и часто обратный универсализации. В этом ряду совершенно особняком стоят публичные библиотеки кода, поскольку заведомо неизвестно где и на какой нагрузке их код будет работать. Но и здесь имеется предел, дальше которого не стоит оптимизировать код только потому, что выигрыш ничтожен по сравнению, например, с накладными расходами на вызов метода. |
И еще замечание относительно публичных библиотек: прежде чем перейти к процессу оптимизации, библиотека должна пожить. Авторы должны услышать замечания, исправить баги, знать, где на практике пользователи чаще всего сталкиваются с проблемами недостаточности производительности.
Поэтому, если вы используете публичные либы, то не стесняйтесь писать их авторам об обнаруженных недостатках или своих пожеланиях - они именно для этого выложили код. Если хотите, это ваша плата за использование. |
Я стартовал топик Портирование, рефакторигн, оптимизации проекта:
http://www.flasher.ru/forum/showthread.php?t=109223 подключайтесь. |
| Часовой пояс GMT +4, время: 13:40. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.