11.02.2016, 15:32
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 51
|
|
Прирост производительности типизированных переменных
Чисто теоретически интересует, какой в среднем прирост производительности javascript будет, если везде будут использоваться только типизированные переменные и не будет var'ов ?
|
|
11.02.2016, 22:48
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Сообщение от webgame
|
Чисто теоретически интересует, какой в среднем прирост производительности javascript будет, если везде будут использоваться только типизированные переменные и не будет var'ов ?
|
При декларации переменной не меняй ей потмо тип и будет тебе прирост производительности. Во всех современных JS VM крутится очень хитрый JIT, который сам эти типы и выводит, просто не надо складывать строки с числами в таком случае
|
|
12.02.2016, 04:38
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 51
|
|
kobezzza,
Ты все верно говоришь, но я никак не могу понять, почему тогда JS медленнее c++ ? Я вот делал простой короткий, но очень длинный цикл с простыми расчетами типа a+b на c++, asm.js и на обычном ES5. Разница в скорости в несколько раз. Откуда она берется, если код настолько простой и короткий, что браузер должен был перевести его в нативный код и тупо исполнять? Тестил на FF v44.
|
|
12.02.2016, 11:43
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Ну во первых в JS JIT работает на уровне функций, т.е. после множественного вызова функции JIT обратит на неё внимание и попробует оптимизировать.
В ASM.js AOT, а не JIT, т.е. всё компилится непосредственное перед запуском программы, а не во время, а это возможно благодаря явной информации о типах и общей строгости диалекта. С другой стороны JIT, не замедляет старт приложения, а вот AOT очень даже может.
Если посмотреть профилировщик в JS, то значительная часть времени уходит на сборку мусора, а в ASM.js никакой сборки мусора нет и прямой доступ к памяти, как в С, что также даёт бешеный профит.
Ну и последнее: обычно в asm.js идёт портирование из С/С++, который в свою очередь был скомпилен, а компиляторы С просто монстры с точки зрения оптимизаций на этапе компиляции, но конечно же, это не быстрый процесс
|
|
12.02.2016, 11:51
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Но с другой стороны: благодаря мощной конкуренции на рынке JS VM, скорость работы VM постоянно растёт и сделала JS одним из самых быстрых скриптовых языков в мире. Например, пол года назад гугл стал интегрировать новый JIT в V8 - TurboFan, который использует информацию ES6 и значительно ускоряет работу или же если взять Chackra Core от MS - то он вообще звездолёт
|
|
14.02.2016, 00:46
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 51
|
|
Сообщение от kobezzza
|
Ну во первых в JS JIT работает на уровне функций, т.е. после множественного вызова функции JIT обратит на неё внимание и попробует оптимизировать.
В ASM.js AOT, а не JIT, т.е. всё компилится непосредственное перед запуском программы, а не во время, а это возможно благодаря явной информации о типах и общей строгости диалекта. С другой стороны JIT, не замедляет старт приложения, а вот AOT очень даже может.
Если посмотреть профилировщик в JS, то значительная часть времени уходит на сборку мусора, а в ASM.js никакой сборки мусора нет и прямой доступ к памяти, как в С, что также даёт бешеный профит.
Ну и последнее: обычно в asm.js идёт портирование из С/С++, который в свою очередь был скомпилен, а компиляторы С просто монстры с точки зрения оптимизаций на этапе компиляции, но конечно же, это не быстрый процесс
|
Я все равно не могу понять. Вот смотри, я описал тесты в которых не должно быть ничего из твоего описания. Во-первых, у меня в тесте нет вызова функций - там простой for цикл. Во-вторых, JIT компиляция точно так же переводит в нативный бинарный машинный код, как и AOT, и исполняет этот мой простой цикл именно так. Нет никакого смысла каждую итерацию цикла чтото там опять компилировать, интерпретировать, отслеживать и тд, там ничего не меняется, и типы переменных тоже, а значит и сборщик мусора не нужен, на него не тратиться время. Единственная причина почему может быть медленнее, это если компилятор хуже. C++ это AOT, а значит он может долго анализировать код , делать много проходов для анализа, перебирать варианты как и что лучше сделать, а в JS надо как можно быстрее компилировать, да еще не всё вместе анализировать, а частями, да еще и сам компилятор хуже. Но всё остальное по уму не должно влиять.
|
|
14.02.2016, 01:57
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Цитата:
|
Во-вторых, JIT компиляция точно так же переводит в нативный бинарный
|
Как бы никто и не спорит. Только JIT это делает во время работы программы, а не сразу + есть много способов в JS отменить работу JIT в рамках функции - например использовать eval.
Цитата:
|
Нет никакого смысла каждую итерацию цикла чтото там опять компилировать, интерпретировать
|
Обычно используется перевод кода в байткод, а затем JIT уже в машинный, но это уже каждая VM по своему, например V8 сразу генерит машинный код, т.е. их получается 2 - оптимизированный и нет.
Цитата:
|
Единственная причина почему может быть медленнее, это если компилятор хуже.
|
Конечно нет, JS очень динамичный язык из из-за кучи перестраховок падает производительность.
С++ это как правило тупо компиляция в машинный код и распространение уже скомпиленной программы.
JIT - компиляция во время исполнения программы (параллельно с работой программы);
AOT - компиляция перед непосредственным запуском.
***
А вообще, как бы перед тем как строить теории, догадки и т.д. нужно как минимум провести тесты и определить через профилирование на что тратится время и работает ли JIT.
В отладчике ФФ или Хрома всё нужное есть. Также тут можно прочитать про тестирование http://habrahabr.ru/company/mailru/blog/273839/
Последний раз редактировалось kobezzza, 14.02.2016 в 02:30.
|
|
14.02.2016, 08:35
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 51
|
|
На счет профилирования это ты верно сказал, надо будет посмотреть. Потому что я не вижу ни одной причины зачем бы нужно было, как ты говоришь, делать JIT компиляцию во время выполнения такого цикла, который тупо выполняет пару команд сложения триллион раз нет ни одной причины даже переводить JS в байткод или байткод в машинный во время выполнения этого цикла, для таких простых циклов это делается до его выполнения, и по уму один раз генерится машинный код и далее уже только он и выполняется, поскольку в теле цикла нет никаких зависимостей с внешним миров, вызовов функций, преобраования типов и тд., все операции и типы данных легко приводятся и укладываются в стандартные регистры процессора. Я все это говорю потому что еще 17 лет назад писал очень сложные оптимизации на ассемблере, и прекрасно понимаю, как работает процессор на самом низком уровне. А постоянное увеличение производительности VM говорит только о тупости их создателей, потому что все типы оптимизация о которых я читал до 2015 года, придуманы еще 20 лет назад, и очевидны были давно.
P.s. Я с тобой ни в коем случае не спорю, поскольку в JS ты понимаешь лучше меня, просто болит душа за него, потому что на других форумах я постоянно читаю много упреков в сторону JS и node.js, особенно от c++ программистов, которые считают что на нем пишут те, кто не умеет программмировать, а причина именно в скорости выполнения. Буду благодарен, если ты поделишься со мной ссылками на хорошие статьи про ручную оптимизацию JS в плане различных способов указания JIT компилятору как нужно обрабатывать конкретные участки кода (к примеру, я точно знаю что посетителю более привлекательно подождать подольше вначале при компиляции, но во время выполнения, чтобы работало побыстрее), и о новых ES6/ES7 нюансах, которые помогают компилятору и VM быстрее работать, как можно помогать подсказаками в коде, где и как лучше обрабатывать (к примеру, чтобы я решал какой вызов функции оставить вызовом, а где вставив в это место ее вызова само тело функции, да и вообще о всяком таком), как уменьшить нагрузку на сборщик мусора (к примеру, я могу не использовать var во время выполнения повсеместно, а создать Typed Array один раз и хранить там все переменные, если это поможет, правда я не знаю как заменить обращение к таким переменным в коде с массив[n] на нормальные имена для удобства, конечно если это возможно и вообще имеет смысл думал asm.js использовал, но этот Emscripten настолько убогий, сырой, неудобный, да и лишается смысл, потому что писать уже надо на c++, что сложнее чем на JS для клиент-серверных приложений в браузере. Спасибо за ссылку на хабре
Последний раз редактировалось webgame, 14.02.2016 в 08:55.
|
|
14.02.2016, 12:26
|
|
Профессор
|
|
Регистрация: 23.12.2013
Сообщений: 1,856
|
|
webgame,
Цитата:
|
и о новых ES6/ES7 нюансах, которые помогают компилятору и VM быстрее работать, как можно помогать подсказаками в коде, где и как лучше обрабатывать
|
Я не Кобеззза, но и у меня кое что есть для тебя https://groups.google.com/forum/#!ms...Q/5ENNAiUzEgAJ
Если в кратце, то со скоростью в ES6 всё не так радужно, как могло казаться.
|
|
14.02.2016, 18:04
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 51
|
|
Спасибо. Интересно. Но как я понял это все касается только V8, может чакра всех спасет?)))
|
|
|
|