Dorival Pedroso, PowP has a lot of code. PowG is simpler and it is modestly slower for small values of n and much faster for larger values of n.
func PowG(x float64, n uint32) float64 { y := 1.0 for i := n; i > 0; i >>= 1 { if i&1 == 1 { y *= x } x *= x } return y } BenchmarkPowP1 1000000000 2.89 ns/op BenchmarkPowP5 100000000 13.6 ns/op BenchmarkPowP10 50000000 29.2 ns/op BenchmarkPowP20 20000000 89.6 ns/op BenchmarkPowP200 200000 11666 ns/op BenchmarkPowG1 1000000000 2.66 ns/op BenchmarkPowG5 100000000 17.9 ns/op BenchmarkPowG10 30000000 45.1 ns/op BenchmarkPowG20 20000000 97.7 ns/op BenchmarkPowG200 300000 3972 ns/op Peter On Friday, August 4, 2017 at 10:08:36 AM UTC, Dorival Pedroso wrote: > > Since my ASM skills are limited, for positive integers, I'm planning on > using: > > // PowP computes real raised to positive integer xⁿ > func PowP(x float64, n uint32) (r float64) { > if n == 0 { > return 1.0 > } > if n == 1 { > return x > } > if n == 2 { > return x * x > } > if n == 3 { > return x * x * x > } > if n == 4 { > r = x * x > return r * r > } > if n == 5 { > r = x * x > return r * r * x > } > if n == 6 { > r = x * x * x > return r * r > } > if n == 7 { > r = x * x * x > return r * r * x > } > if n == 8 { > r = x * x * x * x > return r * r > } > if n == 9 { > r = x * x * x > return r * r * r > } > if n == 10 { > r = x * x * x > return r * r * r * x > } > r = x * x * x > r = r * r * r * x > var i uint32 > for i = 11; i <= 20; i++ { > r *= x > if n == i { > return > } > } > return math.Pow(x, float64(n)) > } > > which gives a speedup of 5-8 times for small positive integers (<20). the > case of negative integers could be handled too. > > output: > BenchmarkPowP10-32 50000000 30.4 ns/op > BenchmarkPowP10std-32 5000000 247 ns/op > BenchmarkPowP20-32 20000000 98.2 ns/op > BenchmarkPowP20std-32 3000000 561 ns/op > BenchmarkPowP200-32 200000 10145 ns/op > BenchmarkPowP200std-32 200000 9231 ns/op > > all files are here: > https://gist.github.com/cpmech/9f871df5b59fa8407221b0d3fb361a3d > > I'm also looking at the Cephes library: http://www.netlib.org/cephes/ for > ideas > > maybe we could have a similar function in Go (and many more optimised > ones, especially for complex numbers...) > > cheers > d > > > > On Friday, August 4, 2017 at 4:20:41 PM UTC+10, Dorival Pedroso wrote: >> >> I've noticed that this C code: >> >> #include "math.h" >> int main() { >> double x = 2.5; >> int Nmax = 10000000; >> for (int N=0; N<Nmax; N++) { >> for (int i=0; i<20; i++) { >> pow(x, i); >> } >> } >> } >> >> can run up to 50x faster than this Go code: >> >> package main >> >> import "math" >> >> func main() { >> x := 2.5 >> Nmax := 10000000 >> for N := 0; N < Nmax; N++ { >> for i := 0; i < 20; i++ { >> math.Pow(x, float64(i)) >> } >> } >> } >> >> The C code was compiled with: gcc -O2 ccode.c -o ccode -lm >> then run with time ./ccode >> >> The Go code was compiled with: go build gcode.go >> then run with time ./gcode >> >> I've used the time command on Linux (Ubuntu) to get some estimate. >> >> So the question is: how can we make the Go code faster? >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.