Benchmark of Perfect Numbers I wrote a piece of code to benchmark the detection of perfect numbers up to 10000.  The original code is here, in C:


#include &lt;stdio.h&gt;

int isPerfectNumber(int num) {
    if (num == 1) { return 0; }

    int i, c = num - 1;
    for (i = 2; i &lt;= num / 2; ++i) {
        if (num % i == 0) { c -= i; }
    }

    return c == 0;
}

int main(int argc, char* argv[]) {
    int i;
    for (i = 0; i &lt; 10000; ++i) {
        if (isPerfectNumber(i)) {
            printf("%d\n", i);
        }
    }
    return 0;
}



I then wrote the same code in a number of different languages (C, C#, Java, V8 Javascript, Python and Go).

After benchmarking, I got the following results:


C: 92.8 ms
C#: 97.9 ms
Go: 208.85 ms
Java: 130.65 ms
V8 Javascript: 279.15 ms
Python: 1126.35 ms


I expected pretty much exactly this pattern of fastest to slowest, except for Go.  Why is my Go implementation so slow?  I admit I know very little about Go but I was under the impression that since it is a compiled language it is likely to be as fast as at least C# was.

Here is my Go implementation:

package main

import "fmt"

func main() {
    for i := 0; i &lt; 10000; i++ {
        if (isPerfectNumber(i)) {
            fmt.Println(i)
        }
    }
}

func isPerfectNumber(num int) bool {
    if num == 1 { return false }

    c := num - 1
    for i := 2; i &lt;= num / 2; i++ {
        if num % i == 0 { c -= i }
    }

    return c == 0
}


Have I just mucked something up or are the results I am seeing accurate?

FYI: I benchmark by running the code 10 times without timing it, then running another 20 times and take the average of those 20 tests.
I've bumped the number to 100000 and profiled. It seems that modulo operation is the most expensive here:

ROUTINE ======================== main.isPerfectNumber in /tmp/so/main.go
    31.72s     31.72s (flat, cum)   100% of Total
         .          .     19:   if num == 1 {
         .          .     20:       return false
         .          .     21:   }
         .          .     22:
         .          .     23:   c := num - 1
     2.35s      2.35s     24:   for i := 2; i &lt;= num/2; i++ {
    29.37s     29.37s     25:       if num%i == 0 {
         .          .     26:           c -= i
         .          .     27:       }
         .          .     28:   }
         .          .     29:
         .          .     30:   return c == 0


It seems that C compilers are able to optimize modulo here, while the Go compiler cannot. I'd suggest opening an issue about it on the Go bug tracker. If C can do that, Go should as well.