Hi guys. I know that all benchmarks are futile, but I would like to understand 
why the C counterpart of the following Nim snippet to calculate the number of 
primes in an interval is more than 3 times faster than Nim.

Nim version: 
    
    
    # bm_nim.nim
    
    proc count_prime_numbers(n_low, n_high: int): int =
      var nbr = n_low
      if nbr mod 2 == 0:  # make sure we start with an uneven number
        nbr += 1
      while nbr < n_high:
        let limit = nbr div 2
        var is_prim = true
        for divisor in 2..<limit:
          if nbr mod divisor == 0:
            is_prim = false
            break
        if is_prim:
          result += 1
        nbr += 2
    
    when isMainModule:
      echo(count_prime_numbers(3, 200000))
    

C version: 
    
    
    // bm_c.c
    #include <stdio.h>
    
    int count_prime_numbers(int n_low, int n_high) {
      int count_of_primes = 0;
      int is_prim, zahl, divisor, limit;
      zahl = n_low;
      if (zahl % 2 == 0) {zahl += 1;}
      while (zahl < n_high) {
        is_prim = 1;
        limit = zahl / 2;
        for (divisor = 2; divisor < limit; divisor++) {
          if (zahl % divisor == 0) {
            is_prim = 0;
            break;
          }
        }
        if (is_prim == 1) {
          count_of_primes++;
        }
        zahl += 2;
      }
      return count_of_primes;
    }
    
    int main(void)
    {
        printf("%d", count_prime_numbers(3, 200000));
            return 0;
    }
    

compiled and run with:
    
    
    $ nim -d:release c bm_nim
    # <compiler output omitted>
    $ time ./bm_nim
    17983
    
    real    0m8.406s
    user    0m8.404s
    sys     0m0.000s
    
    $ gcc bm_c.c -o bm_c -O3
    $ time ./bm_c
    17983
    real    0m2.607s
    user    0m2.604s
    sys     0m0.000s
    

Some remarks:

  * I know that this is not the most efficient way to calculate prime numbers, 
I just wanted to compare performance in some nested loops.
  * I know very little about C.
  * Things I have tried (all without significant change of the performance of 
the Nim snippet):
    
    * replaced the for loop by a while loop
    * re-implemented the modulo operator
    * used uint8 instead of bool for is_prim



In these comparable programs, where does Nim lose performance over C? Are there 
options I missed?

Loving Nim, keep up the great work! I tried Rust (again) over the last couple 
of days, but Nim is way easier to use!

Kind regards,

Axel 

Reply via email to