Я провел несколько экспериментов, чтобы исследовать выполнимость альтернативных языков на стороне сервера. Больше для академических, чем для практических целей.
Три, которые я выбрал, были Javascript (на узле), PHP и Dart.
Я попытался создать честный тест, используя итерации. Эти тесты заключаются в следующем:
Javascript:
run();run();run();run();run();run();run();run();run();
function run() {
var sample = '';
for (var i = 0; i < 20000000; i++) {
sample = 'sample-'+i;
}
}
PHP:
<?php
run();run();run();run();run();run();run();run();run();
function run()
{
$sample = '';
for ($i = 0; $i < 20000000; $i++) {
$sample = 'sample-'.$i;
}
}
Dart:
main() {
run();run();run();run();run();run();run();run();run();
}
run()
{
String sample = '';
for (int i = 0; i < 20000000; i++) {
sample = 'sample-'+i.toString();
}
}
Перед тем, как начать тесты, я ожидал, что порядок скорости от самой быстрой до самой медленной будет:
Dart> Javascript> PHP
Однако истинные результаты, которые я получил, меня удивили:
> time node j.js
real 0m19.014s
user 0m19.093s
sys 0m0.068s
> time php p.php
real 0m24.543s
user 0m24.524s
sys 0m0.008s
> time dart d.dart
real 0m27.697s
user 0m27.788s
sys 0m0.149s
Я хотел бы знать, отражают ли эти результаты истинную разницу в производительности между этими средами выполнения, или сам тест является неполным или несправедливым?
ОБНОВИТЬ:
В ответ на комментарии я уточню несколько вещей.
Я знаю, что настоящее приложение не будет выглядеть так, и что настоящие узкие места возникнут из-за чрезмерного использования ресурсов / соединений. В таких ситуациях я всегда буду выбирать язык лайк большинство.
Я включил PHP в тест, потому что это язык, который я активно использую. Я знаком с JS, но мне неудобно использовать его для больших приложений. Моим основным интересом было сравнение производительности между Dart и JS с использованием движка V8, изобретенного Google, который показал, что DartVM работает быстрее.
Этот конкретный тест должен был определить производительность простого повторения высокой интенсивности (I.E, большой цикл и конкатенация). Мне нужно будет выполнить аналогичный тест для высокой интенсивности ввода-вывода.
Я не думаю, что правильно задал вопрос, что я надеялся узнать из публикации, почему в этом относительно простом примере Dart работает медленнее итераций, чем V8 Engine.
Тесты, как правило, отстой, но они все же дают некоторую ценность, по крайней мере, если они хорошо обработаны.
Команда Dart предоставляет несколько тестов с результатами на сайте dartlang.org, см. https://www.dartlang.org/performance/
Он не представляет ничего, кроме производительности int.toString и String. + При использовании вне какого-либо контекста.
Например, попробуйте изменить версию Dart на:
main() {
run();run();run();run();run();run();run();run();run();
}
run() {
String sample = '';
for (int i = 0; i < 20000000; i++) {
sample = 'sample-$i';
}
}
Если я это сделаю, я получу производительность на том же уровне, что и JavaScript.
Хороший удалитель мертвого кода может удалить всю вашу функцию: поскольку вы никогда не читаете «образец», назначения для него могут быть исключены. Если int.toString и String. + Распознаются как не имеющие побочных эффектов (что возможно), то это выражение также можно удалить. Тогда у вас есть простой цикл с целочисленным индексом от 0 до 20000000, который, как известно, заканчивается без побочных эффектов, так что его тоже можно удалить.
Когда вы делаете тесты, всегда убедитесь, что у вас есть конечный результат, который каким-то образом зависит от всех вычислений, которые вы хотите измерить, или когда-нибудь оптимизирующий компилятор просто удалит все это и завершит работу за ноль секунд.
Конкатенация строк может быть реализована различными способами. Например, V8 использует «cons-strings» для объединения двух строк. То есть они на самом деле не объединяют строки, а создают новое представление, которое говорит: «эта строка является объединением этих двух других строк». Это особенно эффективно при создании больших струн меньшими шагами. Тем не менее, он также может использовать больше памяти.
Видеть это ошибка, где нам пришлось изменить реализацию строкового буфера dart2js, потому что он взрывался в памяти. Причина заключалась в том, что были использованы все ресурсы памяти.
Следовательно, ваш эталонный тест не отражает фактическую скорость трех vms.