Closed
Description
Dart SDK version: 2.13.0-116.0.dev (dev) (Sun Mar 7 18:57:20 2021 -0800) on "windows_x64"
Came across an article regarding FFI
, there was a comparison of Dart performance to gcc. The sample code was trivial and used log()
in a loop and the difference in performance was 10x. Got curious and did my own micro-benchmarks using Dart, gcc and .NET 5.
Empty loop (not included in code below) and sin()
(included) gave similar results for all 3 languages, logarithm is ~5-25x slower with Dart (both VM/Jit and AOT) - ~20s vs 3-0,7s.
Results, console output
Dart
PS C:\src\dart_log> dart bin/main.dart
Log: 18.420680733952366, 20454ms
Sin: 0.8091447235887737, 3269ms
Sin: 0.8091447235887737, 3200ms
Log: 18.420680733952366, 17498ms
Sin: 0.8091447235887737, 2497ms
PS C:\src\dart_log> dart compile exe bin/main.dart
Info: Compiling without sound null safety
Generated: c:\src\dart_log\bin\main.exe
PS C:\src\dart_log> bin/main
Log: 18.420680733952366, 17825ms
Sin: 0.8091447235887737, 2467ms
Log: 18.420680733952366, 17575ms
Sin: 0.8091447235887737, 2496ms
Log: 18.420680733952366, 17608ms
Sin: 0.8091447235887737, 2442ms
.NET 5/C# (app built in Release mode)
Log: 18,420680733952366, 731ms
Sin: 0,8091447235887737, 3115ms
Log: 18,420680733952366, 702ms
Sin: 0,8091447235887737, 3077ms
Log: 18,420680733952366, 725ms
Sin: 0,8091447235887737, 3107ms
gcc/C++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project - 8.1.0)
PS C:\src\cpp_log> gcc -o main -lm main.cpp -O3
PS C:\src\cpp_log> ./main.exe
Log: 18.42, 2876.00ms
Sin: 0.81, 4827.00ms
Log: 18.42, 2962.00ms
Sin: 0.81, 4833.00ms
Log: 18.42, 2899.00ms
Sin: 0.81, 4976.00ms
Dart Code
import 'dart:math';
double log_loop(int n) {
var l = 0.0;
for (var i = 0.0; i < n; i++) {
l = log(i);
}
return l;
}
double sin_loop(int n) {
var l = 0.0;
for (var i = 0.0; i < n; i++) {
l = sin(i);
}
return l;
}
void main(List<String> arguments) {
for (var i = 0; i < 3; i++) {
var sw = Stopwatch()..start();
var result = log_loop(100000000);
sw.stop();
print('Log: $result, ${sw.elapsed.inMilliseconds}ms');
sw.reset();
sw.start();
result = sin_loop(100000000);
sw.stop();
print('Sin: $result, ${sw.elapsed.inMilliseconds}ms');
}
}
C# code
using System;
using System.Diagnostics;
namespace dotnet_log
{
class Program
{
static double log_loop(int n)
{
double l = 0;
for (double i = 0; i < n; i++)
{
l = Math.Log(i);
}
return l;
}
static double sin_loop(int n)
{
double l = 0;
for (double i = 0; i < n; i++)
{
l = Math.Sin(i);
}
return l;
}
static void Main(string[] args)
{
for (var i = 0; i < 3; i++)
{
var sw = new Stopwatch();
sw.Start();
var r = log_loop(100000000);
sw.Stop();
Console.WriteLine("Log: {0}, {1}ms", r, sw.ElapsedMilliseconds);
sw.Start();
r = sin_loop(100000000);
sw.Stop();
Console.WriteLine("Sin: {0}, {1}ms", r, sw.ElapsedMilliseconds);
}
Console.ReadKey();
}
}
}
C++ code
#include <string>
#include <math.h>
#include <time.h>
double log_loop(int n) {
double l = 0;
for (double i = 0; i < n; i++) {
l = log(i);
}
return l;
}
double sin_loop(int n) {
double l = 0;
for (double i = 0; i < n; i++) {
l = sin(i);
}
return l;
}
int main()
{
for (int i = 0; i < 3; i++) {
clock_t sw = clock();
double result = log_loop(100000000);
printf("Log: %.2f, %.2fms\n", result, 1000.0*(clock() - sw)/CLOCKS_PER_SEC);
sw = clock();
result = sin_loop(100000000);
printf("Sin: %.2f, %.2fms\n", result, 1000.0*(clock() - sw)/CLOCKS_PER_SEC);
}
}