Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

perf_pure/perf_pure.fz


# modelled after this repository: https://github.com/JuliaLang/Microbenchmarks
perf_pure =>

  iterations := 5

  assert(b bool) =>
    if(!b)
       panic "assertion failed"

  print_perf(str String, nano_sec u64) =>
    say "fuzion;$str;{nano_sec.as_f64/1E6}"



  fibonacci is

    fib(n u32) u32 is
      if n < 2 n else fib(n-1) + fib(n-2)

    assert(fib(20) = 6765)
    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      fib 20
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
    print_perf "recursion_fibonacci" tmin.get



  parse_integer is
    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      for k in (1..1000) do
        n := random.next_i32 i32.type.max
        str := n.hex
        m:= str.parse_i32_hex.val
        assert(m=n)
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
    print_perf "parse_integers" tmin.get



  mandelbrot is

    complex_abs_2(z_real f64, z_imag f64) =>
      z_real * z_real + z_imag * z_imag

    mandel(real f64, imag f64) =>
      z_real := mut real
      z_imag := mut imag
      c_real := real
      c_imag := imag
      max_iter := 80
      n := mut i32.type.min
      break := mut false
      for k in (1..max_iter) do
        if complex_abs_2 z_real.get z_imag.get > 4.0
          break <- true
          n <- k - 1
        else
          z²_real := z_real.get * z_real.get - z_imag.get * z_imag.get
          z²_imag := z_real.get * z_imag.get + z_imag.get * z_real.get
          z_real <- z²_real + c_real
          z_imag <- z²_imag + c_imag
        until break.get
      if n.get = i32.type.min
        max_iter
      else
        n.get

    mandelperf =>
      mandel_sum := mut 0
      for re := -20.0, re + 1.0 while re <= 5.0 do
        for im := -10.0, im + 1.0 while im <= 10.0 do
          m := mandel (re/10) (im/10)
          mandel_sum <- mandel_sum.get + m
      mandel_sum.get

    mandel_sum := mut 0
    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      mandel_sum <- mandelperf
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
    assert(mandel_sum.get = 14791)
    print_perf "userfunc_mandelbrot" tmin.get



  sort is

    quicksort(T type : numeric, arr Mutable_Array T, low i32, hi i32) =>
      lo := mut low
      i := mut lo.get
      j := mut hi
      while (i.get < hi) do
        pivot := arr[(lo.get+hi)/2]

        while (i.get <= j.get) do
          while (arr[i.get] < pivot) do
            i <- i.get + 1
          while (arr[j.get] < pivot) do
            j <- j.get - 1
          if(i.get <= j.get)
            temp := arr[i.get]
            arr[i.get] := arr[j.get]
            arr[j.get] := temp
            i <- i.get + 1
            j <- j.get - 1

        if (lo.get < j.get)
          quicksort arr lo.get j.get
        lo <- i.get
        j <- hi

    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      mi : mutate is
      mi.go ()->
        d := (mutate.array f64).type.new mi 5000 0.0
        for i in d.indices do
          d[i] := random.next_f64
        quicksort d 0 (d.count - 1)
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
      # NYI quicksort is broken
      # assert (d.reduce (-f64.type.max, true) ((r, t) -> (t, r.values.1 && t >= r.values.0))).values.1
    print_perf "recursion_quicksort" tmin.get



  pi_sum is

    pisum =>
      sum := mut 0.0
      for j in (1..500) do
        sum <- 0.0
        for k in (1..10000) do
          sum <- sum.get + 1.0/ (k.as_f64 * k.as_f64)
      sum.get

    pi := mut 0.0
    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      pi <- pisum
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
    assert((pi.get - 1.644834071848065).abs < 1E-12)
    print_perf "iteration_pi_sum" tmin.get



  iteration_sinc_sum is

    sinc_sum(n i32) =>
      ((0..(n-1)).map f64 (i ->
          f := f64.type.π * i.as_f64
          f64.type.sin f / f
        )).fold f64.type.sum

    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      sinc_sum 1000
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
    print_perf "iteration_sinc_sum" tmin.get



  random_matrix_statistics is

    rand_mat_stat(a i32)
    post 0.5 < rand_mat_stat.this.result.values.0 < 1.0 && 0.5 < rand_mat_stat.this.result.values.1 < 1.0
      =>
        # NYI
      (0.0,0.0)



    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      rand_mat_stat 1000
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
    print_perf "matrix_statistics" tmin.get



  random_matrix_multiplication is

    generate_random_matrix =>
      num.matrix (array2 f64 100 100 (_,_ -> random.next_f64))

    tmin := mut u64.type.max
    for x in (1..iterations) do
      start := time.nano.read
      generate_random_matrix * generate_random_matrix
      elapsed := time.nano.read - start
      tmin <- (if (elapsed < tmin.get) elapsed else tmin.get)
    print_perf "matrix_multiply" tmin.get



  run_benchmarks =>
    fibonacci
    parse_integer
    mandelbrot
    # NYI broken
    # sort
    pi_sum
    iteration_sinc_sum
    # NYI
    # random_matrix_statistics
    random_matrix_multiplication

  run_benchmarks