// Headless benchmark: the same Mandelbrot frame rendered by V and by Dart. // // LD_LIBRARY_PATH=build dart example/lib/fractal_bench.dart // // Also checks the two implementations agree pixel-for-pixel, which is what // makes the timing comparison meaningful. import 'package:vflutter_ffi/vflutter_ffi.dart' as v; import 'mandelbrot_dart.dart'; Future main() async { const view = v.FractalView(width: 800, height: 600, maxIter: 500); final pixels = view.width * view.height; // Warm both paths: first call pays for library load / JIT. v.render(const v.FractalView(width: 64, height: 64, maxIter: 50)); renderDart(const v.FractalView(width: 64, height: 64, maxIter: 50)); final swV = Stopwatch()..start(); final fromV = v.render(view); swV.stop(); final swP = Stopwatch()..start(); final fromParallel = await v.renderParallel(view, tiles: 4); swP.stop(); final swD = Stopwatch()..start(); final fromDart = renderDart(view); swD.stop(); print('${view.width}x${view.height}, maxIter ${view.maxIter} ' '($pixels px)\n'); print('V, one isolate ${swV.elapsedMilliseconds} ms'); print('V, 4 isolates ${swP.elapsedMilliseconds} ms'); print('Dart, one isolate ${swD.elapsedMilliseconds} ms'); print('speedup vs Dart ' '${(swD.elapsedMicroseconds / swV.elapsedMicroseconds).toStringAsFixed(2)}x ' 'serial, ' '${(swD.elapsedMicroseconds / swP.elapsedMicroseconds).toStringAsFixed(2)}x ' 'parallel'); print('\nagreement checks'); print(' V serial vs V parallel : ${_diff(fromV, fromParallel)} bytes differ'); print(' V serial vs Dart : ${_diff(fromV, fromDart)} bytes differ'); } int _diff(List a, List b) { if (a.length != b.length) return -1; var n = 0; for (var i = 0; i < a.length; i++) { if (a[i] != b[i]) n++; } return n; }