Несколько глупых тестов для проверки различий в производительности между версиями Dart.

Имейте в виду, что это не сложный бенчмаркинг. Я просто хотел увидеть эти цифры и подумал, что кому-то они могут показаться интересными. Кроме того, я просто хотел увидеть разницу между версиями Dart 2.19.6 и Dart 3.0.0, а также разницу между типами double и int , которые также будут 64-битными числами на Mac.

Эти бенчмарки совершенно бессмысленны в реальной жизни и просто интересны после перехода на новую версию Dart.

Кроме того, если вам интересно, следите за обновлениями, потому что следующее, чем я планирую поделиться, — это тесты FFI.

Предпосылка

У нас есть только две функции для тестирования Фибоначчи:

double fib(double n) {
  if (n < 2) {
    return n;
  }
  return fibd(n - 2) + fibd(n - 1);
}

int fib(int n) {
  if (n < 2) {
    return n;
  }
  return fibd(n - 2) + fibd(n - 1);
}

И сумма:

double sum(double a, double b) {
  return a + b;
}

int sum(int a, int b) {
  return a + b;
}

Каждый будет вызываться 10 раз, чтобы получить среднее значение.

Также, к моему удивлению, целочисленные операции выполняются в два раза быстрее при вызове dart run по сравнению с скомпилированной версией. Может ли быть так, что Dart JIT все еще более оптимизирован, чем AOT? Пожалуйста, дайте мне знать, если вы знаете ответ или знаете, как произвести более быструю сборку.

Фибоначчи

Я просто хотел проверить некоторые функции, которые имеют больше, чем базовые арифметические операции, в идеале, условие и рекурсию, которые довольно хорошо покрывает Фибоначчи.

Дарт 2.19.6: «бег дротиками»

Double fib: 7381, Fib: 1134903170.0
Int fib: 3661, Fib: 1134903170

Dart 3.0.0: «бег дротиками»

Double fib: 7357, Fib: 1134903170.0
Int fib: 3341, Fib: 1134903170

В этих результатах мы видим, что рекурсия integer завершилась в два раза быстрее. С первого взгляда можно предположить, что просто целочисленная производительность в два раза лучше, но я думаю, что наибольшая потеря производительности связана с вызовами функций, а не с этими арифметическими операциями. Я стал еще более уверен в этом после сравнительного анализа вызовов FFI.

Кроме того, в double comparisons нет разницы в производительности между версиями Dart, что, я думаю, имеет смысл. Команда Dart поддерживает JIT для быстрых итераций разработки, и я не думаю, что у них есть какие-либо цели, чтобы сделать это быстрее.

Теперь давайте проверим скомпилированные исполняемые файлы:

Dart 2.19.6: «dart compile exe»

Double fib: 6629, Fib: 1134903170.0
Int fib: 6726, Fib: 1134903170

Dart 3.0.0: «dart compile exe»

Double fib: 5946, Fib: 1134903170.0
Int fib: 5799, Fib: 1134903170

Как видите, мы получили довольно приятный сюрприз, хотя команда Dart не упомянула об этом во время презентации — и double, и int версии стали примерно на 10% быстрее, что приятно.

Впрочем, вы также можете видеть, что производительность integer в скомпилированной сборке такая же, как и у double, и в два раза медленнее, чем у JIT-версии. Как я уже упоминал, я не уверен, что это связано с производительностью integer. Кажется, что самые большие затраты в примерах Фибоначчи связаны с вызовами функций. Я много лет не фокусировался на сырой производительности, поэтому довольно интересно, насколько дорогими могут быть вызовы функций на разных языках.

Переходим к заключительной части

Сумма

Я просто хотел сырые расчеты без условий. Я думаю, что эти вызовы могут быть встроены в производственные сборки.

Дарт 2.19.6: «бег дротиками»

Double add: 979, sum: 200000000.0
Int add: 569, sum: 200000000

Dart 3.0.0: «бег дротиками»

Double add: 979, sum: 200000000.0
Int add: 551, sum: 200000000

Как видите, картина очень похожа. Опять же, int версия в два раза быстрее, чем double, а общая производительность в JIT-режиме почти такая же.

Dart 2.19.6: «dart compile exe»

Double add: 185, sum: 200000000.0
Int add: 91, sum: 200000000

Dart 3.0.0: «dart compile exe»

Double add: 182, sum: 200000000.0
Int add: 92, sum: 200000000

В скомпилированном режиме мы видим очень интересную картину:

  1. Производительность между версиями одинакова. Опять же, я предполагаю, но я думаю, что простые арифметические операции уже настолько быстры, насколько могли бы быть, а улучшения в Фибоначчи являются результатом других улучшений, таких как стоимость вызова функции.
  2. Учитывая, насколько быстрее производственная сборка, я думаю, что компилятор просто встроил эти функции, полностью устранив стоимость вызова функции.
  3. И int теперь в два раза быстрее по сравнению с double так же как и в JIT.

Этот небольшой тест вдохновил меня на то, чтобы узнать больше о производительности Dart, и я надеюсь, что смогу утолить чье-то любопытство так же, как и мое. Я действительно ищу серию статей «Производительность Dart», подготовленную командой Dart.

Ваше здоровье!