Pull to refresh

Dart vs Node.js: сравниваем производительность на реализациях HTTP сервера

Reading time2 min
Views25K


Всем доброго времени суток!


В этом году с выходом Flutter — фреймворка для кроссплатформенной разработки приложений наметился подъем хайпа по языку Dart. Как и любой перфекционист прокрастинирующий от скуки лентяй я задумался о сравнении производительности серверной реализации виртуальной машины Dart с ее потенциальным антагонистом в лице Node.js. Скажу сразу, что во мне теплилась надежда что Dart победит, а я обрету святой грааль дарующий мне превосходство над потенциальными конкурентами на ближайшие пару тройку пятилеток, но реальность оказалось немного иной...


Инструментарий


  • Тестовая машина: Core I7, SSD, 12GB ОЗУ ( любезно предоставленная моим прошлым работодателем )
  • Нагрузочное тестирование: k6.io ( кстати очень интересный по своей архитектуре фреймворк )

Организация кода приложений


Исходники


Тут я особо решил не заморачиваться и решил следовать рекомендациям, которые вычитывал в свое время на Хабре. В частности:


  • Добавил полезную нагрузку в качестве работы по генерации рандомных данных ( рандомных, чтобы исключить потенциальное кеширование результатов )

    class Human {
        constructor (id, name, surname, age, gender) {
            this.id = id
            this.name = name
            this.surname = surname
            this.age = age
            this.gender = gender
        }
    }

  • Как в Dart так и в Node.js использовал варианты синхронной и асинхронной обработки запроса.
  • Применил варианты нативных решений и варианты решений на отраслевых фреймворках (aqueduct for dart и express for node.js)
  • Так как в ходе исследования удалось получить существенное ускорение работы Dart при использовании aqueduct, который запускает изоляты на каждом ядре, то для целей уравновешивания применил модуль cluster для node.js

Методика тестирования


  • запускал нагрузочные тесты с заданным числом запросов в секунду (500, 750) и ограничением на количество итераций теста (количество завершенных запросов)
  • как приложение так и тестирующий фреймворк были запущены на одной машине, соответственно стоит понимать, что все результаты являются относительными и могут быть сравнимы только друг с другом

Результаты


Native Dart


500 rps



750 rps


  • http_reqs: 309.10154/s

Aqueduct framework for Dart


500 rps



750 rps



Native Node.js


500 rps



750 rps



Node Express with Cluster


500 rps



750 rps



Выводы


  • Конечно многое зависит от того как Вы реализовали логику приложения, я не особо уверен, что мой код является оптимальным как в случае dart так и node.js
    • В частности функцию генерации массива можно было вывести в отдельный worker поток с асинхронным выводом, в моем случае это не было реализовано, поэтому здесь на самом деле не использована вся мошь асинхронщины
    • Как в Dart так и в Node.js вывод можно было организовать через поток
    • Поэтому здесь еще много места как для исследования производительности, так и для оптимизаций
  • Dart в нативной реализации хендлеров показал эпичейский фейл, тем не менее при реализации через фреймворк показал впечатляющие результаты, согласно которым виртуальная машина Dart уже сейчас может составить конкуренцию Node.js
  • На сколько я знаю, в оптимизацию работы V8 вложено колоссальное количество человеко-часов труда, я более чем уверен, что в виртуальную машину Dart вложено гораздо меньше времени. Поэтому у второй возможно есть достаточно больший потенциал для оптимизаций перед V8
Tags:
Hubs:
Total votes 14: ↑12 and ↓2+10
Comments43

Articles