Комментарии 35
А сишное скомпилировано в release?
0
А как на счёт операций с памятью? С Си можно контролировать когда и как выделяешь память, в динамических языках в общем случае нельзя, или это можно но это будех хак (приходится думать на уровень ниже). Тут то у Си и будет выигрыш в производительности.
Например если в цикле мы создаём много разных объектов разных типов или строки, хэши массивы. В си можно один раз под это выделить буфер и создать пару структур. В динамических языках придётся выделять память внутри цикла.
Например если в цикле мы создаём много разных объектов разных типов или строки, хэши массивы. В си можно один раз под это выделить буфер и создать пару структур. В динамических языках придётся выделять память внутри цикла.
+3
мозговзрывательная статья в плане результатов тестов. очень ценный опыт.
+1
Я сделал для себя такой вывод: вызов нативного модуля в V8 — дорогое удовольствие, а не «JS такой же быстрый, как и C++».
+1
это была моя первая мысль
потом возник вопрос — почему тогда при больших итерациях нативный код начинает отставать, когда должно быть наоборот.
потом возник вопрос — почему тогда при больших итерациях нативный код начинает отставать, когда должно быть наоборот.
+1
habrahabr.ru/post/151117/#comment_5123609
вот подтверждение
вот подтверждение
0
собака зарыта в обертке вызова V8, что довольно-таки накладно.
сделайте тест нативного исполнения расчета двойного интеграла и сравните с тестом 2 (нативное исполнение)
Все эти загогулинки мы проходили, когда эксперементировали с написанием нативных вызовах РНР.
сделайте тест нативного исполнения расчета двойного интеграла и сравните с тестом 2 (нативное исполнение)
Все эти загогулинки мы проходили, когда эксперементировали с написанием нативных вызовах РНР.
-1
функция вызывается один раз и выполняется сотни миллисекунд. в таком случае накладные расходы на пересечение границы просто незаметны. они ведь отнюдь не десятками миллисекунд измеряются, а совсем даже долями миллисекунды.
0
однако факт остается фактом…
0
какой факт? что замеры производительности С++ кода на разных машинах, компиляторах и флагах сборки дали разные результаты? это действительно факт.
обратите внимание, я не пытаюсь утверждать, что V8 производит в данном конкретном случае супер код (хотя я посмотрел на него и код достаточно хороший, если не считать бага описнного внизу) или что пересечение границы JS-C++ легче перышка. я утверждаю другое: разница в десятки миллисекунд на таком коде не может быть объяснена задержками при пересечении этой границы.
более того, я даже склоняюсь ко мнению, что у автора что-то со флагами компиляции не так — из-за чего скорость С++ного кода оказалась такой странной. но для подтверждения надо посмотреть на то, что его компилятор породил в этом месте. (еще заметьте, что и время исполнения обычного С++ного варианта и CUDA-вского включают в себя время пересечения границы JS-C++, т.е. оно меньше 17ms).
обратите внимание, я не пытаюсь утверждать, что V8 производит в данном конкретном случае супер код (хотя я посмотрел на него и код достаточно хороший, если не считать бага описнного внизу) или что пересечение границы JS-C++ легче перышка. я утверждаю другое: разница в десятки миллисекунд на таком коде не может быть объяснена задержками при пересечении этой границы.
более того, я даже склоняюсь ко мнению, что у автора что-то со флагами компиляции не так — из-за чего скорость С++ного кода оказалась такой странной. но для подтверждения надо посмотреть на то, что его компилятор породил в этом месте. (еще заметьте, что и время исполнения обычного С++ного варианта и CUDA-вского включают в себя время пересечения границы JS-C++, т.е. оно меньше 17ms).
+1
какой факт? что замеры производительности С++ кода на разных машинах, компиляторах и флагах сборки дали разные результаты? это действительно факт.
обратите внимание, я не пытаюсь утверждать, что V8 производит в данном конкретном случае супер код (хотя я посмотрел на него и код достаточно хороший, если не считать бага описнного внизу) или что пересечение границы JS-C++ легче перышка. я утверждаю другое: разница в десятки миллисекунд на таком коде не может быть объяснена задержками при пересечении этой границы.
более того, я даже склоняюсь ко мнению, что у автора что-то со флагами компиляции не так — из-за чего скорость С++ного кода оказалась такой странной. но для подтверждения надо посмотреть на то, что его компилятор породил в этом месте. (еще заметьте, что и время исполнения обычного С++ного варианта и CUDA-вского включают в себя время пересечения границы JS-C++, т.е. оно меньше 17ms).
обратите внимание, я не пытаюсь утверждать, что V8 производит в данном конкретном случае супер код (хотя я посмотрел на него и код достаточно хороший, если не считать бага описнного внизу) или что пересечение границы JS-C++ легче перышка. я утверждаю другое: разница в десятки миллисекунд на таком коде не может быть объяснена задержками при пересечении этой границы.
более того, я даже склоняюсь ко мнению, что у автора что-то со флагами компиляции не так — из-за чего скорость С++ного кода оказалась такой странной. но для подтверждения надо посмотреть на то, что его компилятор породил в этом месте. (еще заметьте, что и время исполнения обычного С++ного варианта и CUDA-вского включают в себя время пересечения границы JS-C++, т.е. оно меньше 17ms).
+1
«Если вы не умеете писать качественный код на C++ с низкоуровневой оптимизацией, то нет смысла пытаться написать нативное расширение для ускорения производительности.» — вот с этим согласен. Тут так и хочется взять что то типа liboil или накрайняк самим на SSE перенести, гарантирую 4x прирост.
0
Интересно было бы узнать время С++ версии, запущенной напрямую, а не через Node.js.
+8
НЛО прилетело и опубликовало эту надпись здесь
Результаты меня поразили. Поэтому я решил проверить на других языках, после чего вообще впал в ступор.
Функция: integrate(-4,4,-4,4,1024);
Функция: integrate(-4,4,-4,4,1024);
Perl result = 127.999997360281
Perl time = 5295.28713226318
PHP result = 127.99999736028
PHP time = 3503.4229755402
JS result = 127.99999736028109
JS time = 550
+6
Вот ещё тест на чистом С, без js оберток.
C result = 127.999997
C time = 210.000000
+2
производительнее в 2 раза -впечатляет, спасибо
0
Впечатляет то что нода на данном тесте прозводительнее пела почти в 10 раз, и произвидительнее пхп в 6 раз.
Хотя в простом тесте на сетевые соединения (получить коннект, ответить, отвалиться), перл обгонял ноду примерно на 40%.
Хотя в простом тесте на сетевые соединения (получить коннект, ответить, отвалиться), перл обгонял ноду примерно на 40%.
0
тесты скорости лучше сопровождать исходниками
+ у Perl есть PDL для манипуляций с числовыми данными:
на Atom n400 ~ 0.8sec
+ у Perl есть PDL для манипуляций с числовыми данными:
use strict;
use PDL;
use Benchmark qw(:all :hireswallclock);
timethis(1, sub { print integrate(-4,4,-4,4,1024)."\n" });
sub integrate {
my ($x0,$x1,$y0,$y1,$steps) = @_;
my $d = zeroes(float, $steps, $steps);
my ($x, $y) = ( $d->xlinvals($x0, $x1), $d->ylinvals($y0, $y1) );
sum(sin($x * $y) / (1 + sqrt($x**2 + $y**2)) + 2) * ($x1-$x0) * ($y1-$y0) / $steps**2;
}
на Atom n400 ~ 0.8sec
+1
Стоит сказать, что это не чистый перл, а насколько помню, в pdl используются так же C библиотеки?
Ну и у меня результат для вашего теста следующий:
Что тоже дольше чем для чистого JS.
Ну и у меня результат для вашего теста следующий:
Perl PDL result = 128
Perl PDL time = 1171.44012451172
Что тоже дольше чем для чистого JS.
0
А если интересны исходники на которых тестил, то залил на гитхаб github.com/Mikxail/perl_vs_node
0
да, pdl — xs модуль на cpan, т.ч. «cpan PDL» или, если debian, то «apt-get install pdl» )
судя по скорости nodejs, он явно хорошо предпроцессит чистый js в чтото иное, отчасти скомпилированное
p.s. запулил на гитхабе альтернативный вариант на perl без PDL — получилось ~ в 2.5 раз быстрее
судя по скорости nodejs, он явно хорошо предпроцессит чистый js в чтото иное, отчасти скомпилированное
p.s. запулил на гитхабе альтернативный вариант на perl без PDL — получилось ~ в 2.5 раз быстрее
0
Когда я писал этот тест, мне не хотелось делать различий от js. Понятно что тест нужно написать как вы запулили, но это будет отличаться от жс. Возможно nodejs сам оптимизирует до такой конструкции, поэтому и получается быстрее.
Но даже в новом, оптимизированном, варианте на перле, всё равно скорость отстает от скорости на ноде.
Так что остается порадоваться за производительность математических вычислений в v8. Но при этом желать большей производительности на сокетах.
Но даже в новом, оптимизированном, варианте на перле, всё равно скорость отстает от скорости на ноде.
Так что остается порадоваться за производительность математических вычислений в v8. Но при этом желать большей производительности на сокетах.
0
думаю, ваш perl код медленее из-за 3-х объявлений «my» на каждом шаге интегрирования.
nodejs быстр, т.к. — developers.google.com/v8/design#mach_code
nodejs быстр, т.к. — developers.google.com/v8/design#mach_code
V8 compiles JavaScript source code directly into machine code when it is first executed. There are no intermediate byte codes, no interpreter.
0
думаю, ваш perl код медленее из-за 3-х объявлений «my» на каждом шаге интегрирования.
Не совсем так. Объявления переменных на каждой итерации конечно замедляет код, но не сильно, разница всего 200мс.
Perl(preinit vars) result = 127.999997360281
Perl(preinit vars) time = 4794.22998428345
Perl result = 127.999997360281
Perl time = 4931.83994293213
0
нужно приводить результаты тестов с одного железа, ибо от этого сильно зависит результат.
-1
а где результаты Си?
0
у меня на ноде v0.8.8 вылазит баг в V8ом выводе представлений (representation inference) из-за которого замена на стэке (on stack replacement) пораждает совершенно бредовый код, в котором он пытается привести заведомо не целое значение к целому из-за чего происходит деоптимизация… в результате код постоянно крутится в неоптимизированной версии.
если же я запрещаю OSR и вызываю integrateJS дважды, то картина с пиковой производительностью получается примерно такая:
баг я зарапортую на эту тему. причина по моей прикидке в том, что начальное значение переменной result — 0 выглядит как целое число и попадая в phi-функцию на границе между нормальным потоком управления и OSR-entry блоком приводит к неправильному выводу представления для этой phi (https://github.com/v8/v8/blob/d3924c236bfca217385eaf5355a96146f0dcc60d/src/hydrogen-instructions.cc#L2567-2576 < — код увидев 0 выберет целое представление) и почему-то посказки (hint) для HUnknownOSRValue на обратной дуге не сработали.
Кстати, если заменить result = 0, на result = 0.1 баг в representation inference по понятным причинам пропадает.
если же я запрещаю OSR и вызываю integrateJS дважды, то картина с пиковой производительностью получается примерно такая:
omega ~/src/temp/perl_vs_node ∳ git diff [master@368da]
diff --git a/integral.js b/integral.js
index 7b11f22..194adb2 100755
--- a/integral.js
+++ b/integral.js
@@ -18,4 +18,5 @@ function integrateJS(x0,xN,y0,yN,iterations){
console.log("JS time = "+(new Date().getTime() - time));
}
-integrateJS(-4,4,-4,4,1024);
\ No newline at end of file
+integrateJS(-4,4,-4,4,1024);
+integrateJS(-4,4,-4,4,1024);
omega ~/src/temp/perl_vs_node ∳ node integral.js [master@368da]
JS result = 127.99999736028109
JS time = 132
JS result = 127.99999736028109
JS time = 115
omega ~/src/temp/perl_vs_node ∳ node --nouse-osr integral.js [master@368da]
JS result = 127.99999736028109
JS time = 122
JS result = 127.99999736028109
JS time = 55
баг я зарапортую на эту тему. причина по моей прикидке в том, что начальное значение переменной result — 0 выглядит как целое число и попадая в phi-функцию на границе между нормальным потоком управления и OSR-entry блоком приводит к неправильному выводу представления для этой phi (https://github.com/v8/v8/blob/d3924c236bfca217385eaf5355a96146f0dcc60d/src/hydrogen-instructions.cc#L2567-2576 < — код увидев 0 выберет целое представление) и почему-то посказки (hint) для HUnknownOSRValue на обратной дуге не сработали.
Кстати, если заменить result = 0, на result = 0.1 баг в representation inference по понятным причинам пропадает.
0
зарепортил баг: code.google.com/p/v8/issues/detail?id=2330
0
omega ~/src/temp/perl_vs_node ∳ git diff [master@368da] diff --git a/integral.js b/integral.js index 7b11f22..194adb2 100755 --- a/integral.js +++ b/integral.js @@ -18,4 +18,5 @@ function integrateJS(x0,xN,y0,yN,iterations){ console.log("JS time = "+(new Date().getTime() - time)); } -integrateJS(-4,4,-4,4,1024); \ No newline at end of file +integrateJS(-4,4,-4,4,1024); +integrateJS(-4,4,-4,4,1024); omega ~/src/temp/perl_vs_node ∳ node integral.js [master@368da] JS result = 127.99999736028109 JS time = 132 JS result = 127.99999736028109 JS time = 115 omega ~/src/temp/perl_vs_node ∳ node --nouse-osr integral.js [master@368da] JS result = 127.99999736028109 JS time = 122 JS result = 127.99999736028109 JS time = 55
извиняюсь, коряво вставил консольный лог :-/
+1
Проверял PHP и JS, по началу было где-то так, но выключил xdebug и стало
PHP2 time = 601.6321182251 PHP2 result = 127.99999736028 JS time = 204 JS result = 127.99999736028109
0
У меня не установлено никакого xdebug. И по моему он по умолчанию не ставится (если честно, я не силен во всех хитростях пхп).
Без xdebug у вас получилась разница в скорости ~3 раза. В моих тестах ~6 раз.
Не исключено что пхп сильно требователен к железу, а т.к. у меня очень слабая виртуалка, то и появилась разница в ваших и моих тестах.
Без xdebug у вас получилась разница в скорости ~3 раза. В моих тестах ~6 раз.
Не исключено что пхп сильно требователен к железу, а т.к. у меня очень слабая виртуалка, то и появилась разница в ваших и моих тестах.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Ускоряем node.js: нативные модули и CUDA