atemerev / skynet

Skynet 1M threads microbenchmark
MIT License
1.05k stars 122 forks source link

Alternative Go version #27

Open nsf opened 8 years ago

nsf commented 8 years ago

Just in case if you're curious. It avoids using channels for communications and uses sync.WaitGroup instead. Results are collected via arrays and then aggregated inside a single goroutine. On my machine it's slightly faster than channel-based one.

package main

import "fmt"
import "time"
import "sync"

func skynet(out *int, num int, size int, div int, wg *sync.WaitGroup) {
    if size == 1 {
        *out = num
        wg.Done()
        return
    }

    var wgInner sync.WaitGroup
    wgInner.Add(div)
    results := make([]int, div)
    for i := 0; i < div; i++ {
        subNum := num + i*(size/div)
        go skynet(&results[i], subNum, size/div, div, &wgInner)
    }
    wgInner.Wait()
    var sum int
    for _, r := range results {
        sum += r
    }
    *out = sum
    wg.Done()
}

func main() {
    start := time.Now()
    var wg sync.WaitGroup
    wg.Add(1)
    var result int
    go skynet(&result, 0, 1000000, 10, &wg)
    wg.Wait()
    took := time.Since(start)
    fmt.Printf("Result: %d in %d ms.\n", result, took.Nanoseconds()/1e6)
}
codygman commented 8 years ago

@nsf I feel like channels are more idiomatic for communicating. @atemerev Do you believe these benchmarks should be a performance free for all pulling out all of the stops or should each language implementation strive to be idiomatic? Something in between?

nsf commented 8 years ago

I'm not implying that my version should be used instead of the one repo has. I just wrote it out of curiosity and sharing it here.

codygman commented 8 years ago

@nsf Awesome! Thanks for sharing it with everyone. I wasn't trying to attack, just wanted to clarify and help improve the benchmark.

XANi commented 8 years ago

Also you might want to include language versions in benchmark results

gyf19 commented 8 years ago
func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    start := time.Now()
    var wg sync.WaitGroup
    wg.Add(1)
    var result int
    go skynet(&result, 0, 1000000, 10, &wg)
    wg.Wait()
    took := time.Since(start)
    fmt.Printf("Result: %d in %d ms.\n", result, took.Nanoseconds()/1e6)
}