Last active
June 9, 2017 11:07
-
-
Save inotnako/ee973b5bc67b0e13686f87046089e993 to your computer and use it in GitHub Desktop.
bench speed transfer by go channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"runtime" | |
"time" | |
) | |
const radius int = 100 | |
type Line struct { | |
Start chan struct{} | |
End chan struct{} | |
} | |
type LineAny struct { | |
Start chan interface{} | |
End chan interface{} | |
} | |
func c(ctx context.Context, r chan struct{}, l chan struct{}) { | |
for { | |
select { | |
case l <- <-r: | |
case <-ctx.Done(): | |
return | |
} | |
} | |
} | |
func cAny(ctx context.Context, r chan interface{}, l chan interface{}) { | |
for { | |
select { | |
case l <- <-r: | |
case <-ctx.Done(): | |
return | |
} | |
} | |
} | |
func makeLineForAny(ctx context.Context, count int) *LineAny { | |
var ( | |
right chan interface{} | |
leftmost = make(chan interface{}) | |
) | |
left := leftmost | |
for i := 0; i < count; i++ { | |
right = make(chan interface{}) | |
go cAny(ctx, right, left) | |
left = right | |
} | |
return &LineAny{ | |
Start: right, | |
End: leftmost, | |
} | |
} | |
func makeLine(ctx context.Context, count int) *Line { | |
var ( | |
right chan struct{} | |
leftmost = make(chan struct{}) | |
) | |
left := leftmost | |
for i := 0; i < count; i++ { | |
right = make(chan struct{}) | |
go c(ctx, right, left) | |
left = right | |
} | |
return &Line{ | |
Start: right, | |
End: leftmost, | |
} | |
} | |
var debug bool | |
func benchPointsWithAny(N int, retry int, any interface{}) { | |
ctx, cancel := context.WithCancel(context.Background()) | |
defer cancel() | |
lineOne := makeLineForAny(ctx, N) | |
go func() { | |
lineOne.Start <- any | |
}() | |
<-lineOne.End | |
var now time.Time | |
if retry == 0 { | |
retry = 1 | |
} | |
var summary time.Duration | |
for r := 0; r < retry; r++ { | |
runtime.Gosched() | |
go func() { | |
now = time.Now() | |
lineOne.Start <- any | |
}() | |
<-lineOne.End | |
dur := time.Since(now) | |
summary += dur | |
per := time.Duration(int64(dur) / int64(N)) | |
if debug { | |
println("\tend", N, dur.String(), `per`, per.String()) | |
} | |
runtime.Gosched() | |
} | |
perIter := time.Duration(int64(summary) / int64(retry)) | |
perSpan := time.Duration(int64(summary) / int64(N*retry)) | |
println("any end", retry, "iter by", N, summary.String(), `per iter`, perIter.String(), `per span`, perSpan.String()) | |
} | |
func benchPointsWithStruct(N int, retry int) { | |
ctx, cancel := context.WithCancel(context.Background()) | |
defer cancel() | |
lineOne := makeLine(ctx, N) | |
go func() { | |
lineOne.Start <- struct{}{} | |
}() | |
<-lineOne.End | |
var now time.Time | |
if retry == 0 { | |
retry = 1 | |
} | |
var summary time.Duration | |
for r := 0; r < retry; r++ { | |
runtime.Gosched() | |
go func() { | |
now = time.Now() | |
lineOne.Start <- struct{}{} | |
}() | |
<-lineOne.End | |
dur := time.Since(now) | |
summary += dur | |
per := time.Duration(int64(dur) / int64(N)) | |
if debug { | |
println("\tend", N, dur.String(), `per`, per.String()) | |
} | |
runtime.Gosched() | |
} | |
perIter := time.Duration(int64(summary) / int64(retry)) | |
perSpan := time.Duration(int64(summary) / int64(N*retry)) | |
println("end", retry, "iter by", N, summary.String(), `per iter`, perIter.String(), `per span`, perSpan.String()) | |
} | |
func runBenchWithEmptyStruct() { | |
now := time.Now() | |
println("start bench line of channels") | |
for _, n := range []int{1, 10, 50, 100, 500, 1000, 1500, 2000, 3000, 5000, 10000, 15000, 20000, 30000, 50000, 100000} { | |
benchPointsWithStruct(n, 1000) | |
} | |
for _, n := range []int{1, 10, 50, 100, 500, 1000, 1500, 2000, 3000, 5000, 10000, 15000, 20000, 30000, 50000, 100000} { | |
benchPointsWithStruct(n, 100) | |
} | |
println("total time: ", time.Since(now).String()) | |
} | |
func runQuickBenchByType(value interface{}) { | |
now := time.Now() | |
fmt.Printf("start bench line of channels with type %T=%#v \n", value, value) | |
for _, n := range []int{1, 10, 50, 100, 500, 1000, 1500, 2000, 3000, 5000} { | |
benchPointsWithAny(n, 100, value) | |
} | |
println("total time: ", time.Since(now).String()) | |
} | |
type ObjectOfProfile struct { | |
Name string | |
LAstName string | |
Age int | |
Addresses []string | |
} | |
func main() { | |
runQuickBenchByType(123234234234) | |
runQuickBenchByType("some long string") | |
runQuickBenchByType([]byte("some long string")) | |
runQuickBenchByType(ObjectOfProfile{ | |
Name: "Aloxa", | |
LAstName: "Alo[ovicj", | |
Age: 100, | |
Addresses: []string{"one address", "second address"}, | |
}) | |
runQuickBenchByType(&ObjectOfProfile{ | |
Name: "Aloxa", | |
LAstName: "Alo[ovicj", | |
Age: 100, | |
Addresses: []string{"one address", "second address"}, | |
}) | |
/* | |
OUTPUT: | |
start bench line of channels with type int=123234234234 | |
any end 100 iter by 1 100.992µs per iter 1.009µs per span 1.009µs | |
any end 100 iter by 10 521.64µs per iter 5.216µs per span 521ns | |
any end 100 iter by 50 2.435705ms per iter 24.357µs per span 487ns | |
any end 100 iter by 100 4.197153ms per iter 41.971µs per span 419ns | |
any end 100 iter by 500 21.697757ms per iter 216.977µs per span 433ns | |
any end 100 iter by 1000 74.355599ms per iter 743.555µs per span 743ns | |
any end 100 iter by 1500 113.894079ms per iter 1.13894ms per span 759ns | |
any end 100 iter by 2000 151.139878ms per iter 1.511398ms per span 755ns | |
any end 100 iter by 3000 231.907636ms per iter 2.319076ms per span 773ns | |
any end 100 iter by 5000 407.937881ms per iter 4.079378ms per span 815ns | |
total time: 1.066662409s | |
start bench line of channels with type string="some long string" | |
any end 100 iter by 1 92.063µs per iter 920ns per span 920ns | |
any end 100 iter by 10 443.099µs per iter 4.43µs per span 443ns | |
any end 100 iter by 50 2.076925ms per iter 20.769µs per span 415ns | |
any end 100 iter by 100 4.546236ms per iter 45.462µs per span 454ns | |
any end 100 iter by 500 26.614944ms per iter 266.149µs per span 532ns | |
any end 100 iter by 1000 93.208854ms per iter 932.088µs per span 932ns | |
any end 100 iter by 1500 120.74241ms per iter 1.207424ms per span 804ns | |
any end 100 iter by 2000 162.649708ms per iter 1.626497ms per span 813ns | |
any end 100 iter by 3000 241.350023ms per iter 2.4135ms per span 804ns | |
any end 100 iter by 5000 388.040779ms per iter 3.880407ms per span 776ns | |
total time: 1.091011002s | |
start bench line of channels with type []uint8=[]byte{0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67} | |
any end 100 iter by 1 83.522µs per iter 835ns per span 835ns | |
any end 100 iter by 10 483.829µs per iter 4.838µs per span 483ns | |
any end 100 iter by 50 2.414048ms per iter 24.14µs per span 482ns | |
any end 100 iter by 100 4.799888ms per iter 47.998µs per span 479ns | |
any end 100 iter by 500 22.686672ms per iter 226.866µs per span 453ns | |
any end 100 iter by 1000 68.551724ms per iter 685.517µs per span 685ns | |
any end 100 iter by 1500 121.471108ms per iter 1.214711ms per span 809ns | |
any end 100 iter by 2000 151.981409ms per iter 1.519814ms per span 759ns | |
any end 100 iter by 3000 231.27773ms per iter 2.312777ms per span 770ns | |
any end 100 iter by 5000 372.85744ms per iter 3.728574ms per span 745ns | |
total time: 1.068445708s | |
start bench line of channels with type main.ObjectOfProfile=main.ObjectOfProfile{Name:"Aloxa", LAstName:"Alo[ovicj", Age:100, Addresses:[]string{"one address", "second address"}} | |
any end 100 iter by 1 101.406µs per iter 1.014µs per span 1.014µs | |
any end 100 iter by 10 466.513µs per iter 4.665µs per span 466ns | |
any end 100 iter by 50 2.099503ms per iter 20.995µs per span 419ns | |
any end 100 iter by 100 4.133073ms per iter 41.33µs per span 413ns | |
any end 100 iter by 500 23.995134ms per iter 239.951µs per span 479ns | |
any end 100 iter by 1000 69.445531ms per iter 694.455µs per span 694ns | |
any end 100 iter by 1500 110.56993ms per iter 1.105699ms per span 737ns | |
any end 100 iter by 2000 152.28048ms per iter 1.522804ms per span 761ns | |
any end 100 iter by 3000 229.757377ms per iter 2.297573ms per span 765ns | |
any end 100 iter by 5000 402.873605ms per iter 4.028736ms per span 805ns | |
total time: 1.038120928s | |
start bench line of channels with type *main.ObjectOfProfile=&main.ObjectOfProfile{Name:"Aloxa", LAstName:"Alo[ovicj", Age:100, Addresses:[]string{"one address", "second address"}} | |
any end 100 iter by 1 101.554µs per iter 1.015µs per span 1.015µs | |
any end 100 iter by 10 485.966µs per iter 4.859µs per span 485ns | |
any end 100 iter by 50 2.145213ms per iter 21.452µs per span 429ns | |
any end 100 iter by 100 4.497195ms per iter 44.971µs per span 449ns | |
any end 100 iter by 500 23.680137ms per iter 236.801µs per span 473ns | |
any end 100 iter by 1000 66.286894ms per iter 662.868µs per span 662ns | |
any end 100 iter by 1500 116.32279ms per iter 1.163227ms per span 775ns | |
any end 100 iter by 2000 151.649327ms per iter 1.516493ms per span 758ns | |
any end 100 iter by 3000 228.717164ms per iter 2.287171ms per span 762ns | |
any end 100 iter by 5000 426.800158ms per iter 4.268001ms per span 853ns | |
total time: 1.092685522s | |
*/ | |
runBenchWithEmptyStruct() | |
/* | |
start bench line of channels | |
end 1000 iter by 1 766.151µs per iter 766ns per span 766ns | |
end 1000 iter by 10 4.283817ms per iter 4.283µs per span 428ns | |
end 1000 iter by 50 21.366935ms per iter 21.366µs per span 427ns | |
end 1000 iter by 100 51.943063ms per iter 51.943µs per span 519ns | |
end 1000 iter by 500 342.599036ms per iter 342.599µs per span 685ns | |
end 1000 iter by 1000 765.441016ms per iter 765.441µs per span 765ns | |
end 1000 iter by 1500 1.173253703s per iter 1.173253ms per span 782ns | |
end 1000 iter by 2000 1.637974442s per iter 1.637974ms per span 818ns | |
end 1000 iter by 3000 2.554174263s per iter 2.554174ms per span 851ns | |
end 1000 iter by 5000 4.36765129s per iter 4.367651ms per span 873ns | |
end 1000 iter by 10000 9.06096461s per iter 9.060964ms per span 906ns | |
end 1000 iter by 15000 13.639098976s per iter 13.639098ms per span 909ns | |
end 1000 iter by 20000 18.038081422s per iter 18.038081ms per span 901ns | |
end 1000 iter by 30000 26.891978796s per iter 26.891978ms per span 896ns | |
end 1000 iter by 50000 44.305771276s per iter 44.305771ms per span 886ns | |
end 1000 iter by 100000 1m28.954706428s per iter 88.954706ms per span 889ns | |
end 100 iter by 1 93.099µs per iter 930ns per span 930ns | |
end 100 iter by 10 491.847µs per iter 4.918µs per span 491ns | |
end 100 iter by 50 2.116806ms per iter 21.168µs per span 423ns | |
end 100 iter by 100 4.84718ms per iter 48.471µs per span 484ns | |
end 100 iter by 500 24.05627ms per iter 240.562µs per span 481ns | |
end 100 iter by 1000 70.194473ms per iter 701.944µs per span 701ns | |
end 100 iter by 1500 121.763719ms per iter 1.217637ms per span 811ns | |
end 100 iter by 2000 163.508092ms per iter 1.63508ms per span 817ns | |
end 100 iter by 3000 267.367803ms per iter 2.673678ms per span 891ns | |
end 100 iter by 5000 463.22094ms per iter 4.632209ms per span 926ns | |
end 100 iter by 10000 885.933694ms per iter 8.859336ms per span 885ns | |
end 100 iter by 15000 1.33264662s per iter 13.326466ms per span 888ns | |
end 100 iter by 20000 1.7933022s per iter 17.933022ms per span 896ns | |
end 100 iter by 30000 2.697646302s per iter 26.976463ms per span 899ns | |
end 100 iter by 50000 4.88693182s per iter 48.869318ms per span 977ns | |
end 100 iter by 100000 9.217214027s per iter 92.17214ms per span 921ns | |
total time: 3m56.147605727s | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment