Skip to content

dart:math, log() function is slow #45414

Closed
@maxim-saplin

Description

@maxim-saplin

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);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.library-math

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions