← All posts tagged JavaScript

SannySanoff

v8project.blogspot.com

А вот когда в жабоскрипт введут опциональную типизацию и напишут (только благодаря этому! потому что смогут!) на нем наконец-то серверный Spring (springframework.org), он будет медленнее запускаться (startup) чем жабовый или быстрее? Вангую что к тому времени процессоры подтянутся и будут все те же 30-40 секунд.

SannySanoff

Мучаюсь (кайфую) с RSA под бровзерами на жабоскрипте.

Вопрос "нафига"? Ответ: потому что сервер писал не я, а на сервер нужно отправлять XMLSec (xml с зашифрованными фрагментами). Да, овер HTTPS, да, я в курсе, что идиотизм. Ключ вшит в код, да, идиотизм, под названием легаси.

Основной проект на GWT, то есть компилируется с жабы на жабоскрипт. Короче, bouncy castle (java open source security framework) был прикручен мною уже давно но под IE 8 оно втыкает, выскакивал диалог, что жабоскрипт перетрудился, не хотите ли его отдохнуть. Тыканье "да продолжай сцуко" (чекбокс отсутствует) после 50 кликов меня утомило, но всё же захотелось посмотреть, сколько реально времени оно скушает.

А моё любимое дело — оптимизировать всякие штуки, и гонять жабоскрипты под бровзерами, но не прямо, а в стороннем интерпретаторе жабоскрипта, написанном на жабе и портированном под бровзерный жабоскрипт — это был такой эксперимент у нас с товарищем не так давно, по нужде.

Для того, чтобы RSA вообще заработало под IE, надо было перевести его в continuation-passing-style с трамплинами (или как это там называют профессора), чтобы их запускать по таймеру. Короче, вооружился рефакторилкой, перевёл, прооптимизировал чтобы работало непрерывными чанками по 500 миллисекунд, замедилось всё процентов на 20%, зато фурычит и диалоги не выскакивают. IE8 работал минут 10-11.

Делается (RSA encode + RSA decode) * 2 REST запроса, и внутри там еще сигнатура считается, тоже чтото на RSA основано.

95% времени оно сидит в операции умножения по модулю ( A * B % C ), которая реализована с помощью алогоритма Montgomery Product . Короче, все так делают. Все три числа большие, несколько сотен десятичных знаков каждое.

В bouncy castle этот алгоритм реализован на жабе с лонгами (long ints). Лонгов в жабоскрипте нету, GWT использует свою LongLib : эмуляцию на объекте с тремя полями целочисленными, по 22 бита на поле (всего выходит 66 бит, 64 стало быть влазит с головой). Лонг там такой:
{ l: 3984394, m: 31231902, h: 9878989987 }. Библиотека содержит умножение деление и весь остальной балаган. Лонги немутабельны, постоянно создается новый объект как результат любой операции.

Решил быть ушлым и забацать те же операции на мутабельном объекте, чтобы без аллокаций, и вдобавок чтобы отличаться, сделал на массиве a[0],a[1],a[2]. За основу взял существующую GWT LongLib, ибо хороша.

— убрал из внутреннего цикла все ссылки на глобальные переменные и this, засунул все в локальные переменнуе.
— заинлайнил в основной цикл всё что мог, все сложения и сдвиги
— убрал всякие проверки на ноль и обходы в умножениях интов, потому что там всегда будет реально везде не ноль и вообще прооптимизировал некоторое умножение лонгов, потому что там в них всегда реально 32 бита только нижние
— прооптимизировал повторные присвоения типа += , которые авторы сделали для красоты кода, сделал деревья выражений со скобками и теперь в локальных переменных только многажды упоминаемые значения.
— второй множитель передал не массивом (b[0],b[1],b[2]), а двумя аргументами b0 и b1, так как b2 всегда ноль, упростился вызывающий код, ушел временный массив.
— в самом конце взял сгенерированный JS код, убрал в нем ~~a[0], оставил a[0], потому что там в жабоскрипт переменной и так целочисленное изза предварительных вычислений.

По результатам: IE8 — говно и в данной задаче неюзабелен. Также фаерфоксу чото поплохело.

IE8(core i7 920): 800 сек -> 165 сек
IE9: ? → 7 сек
IE10: 22 → 5 сек
Хром: 4 → 2 сек
Опера 24: 5 → 6 сек
FF 23/Linux: 17 → 47 сек.
FF 31/Linux: 12 → 22 сек.
samsung I9082, browser : 40 → 12 сек
ipad: safari 84 → 15 sec
ipad: chrome 306 → 110 sec

По результатам профайлера в хроме GC занимал 20%, стал занимать 5%. Мелочь, а приятно.
Хром под IPAD втыкает потому что iOS анально огорожен и не позволяет JIT, а сафари там само себе его разрешает.