当使用 int64 而不是 int32 时,循环性能要慢得多
For loop performance much slower when using int64 instead of int32
我正在尝试找出有关性能的最佳实践。
我注意到为 for 循环指定整数类型可能会极大地影响性能(在我的例子中是 x2 倍)。
我的问题是,使用 int64 是否应该比使用 int32 慢得多,或者我的代码中遗漏了什么?
我使用的代码:
a.go
package main
import (
"fmt"
"time"
"runtime"
"strconv"
)
func main() {
start := time.Now()
var x1 int // later change all int to int32 or int64
for i := int(0); i <= int(1000000000); i++ {
x1 = x1 + i
}
t := time.Now()
elapsed := t.Sub(start)
fmt.Println(x1)
fmt.Println(elapsed)
fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
fmt.Println(strconv.IntSize)
}
x1 使用 int32 输出
C:\...>go build a.go
C:\...>a
-243309312
238.3333ms
gc amd64 windows
64
使用 int64 输出 x1
C:\...>go build a.go
C:\...>a
500000000500000000
467.7835ms
gc amd64 windows
64
更新
我尝试了@Giulio Micheloni 的建议并获得了更准确的基准。
goos: windows
goarch: amd64
BenchmarkInt64-12 1000000000 0.234 ns/op 0 B/op 0 allocs/op
PASS
ok _/c_/.../.../Desktop 0.402s
Success: Benchmarks passed.
goos: windows
goarch: amd64
BenchmarkInt32-12 1000000000 0.231 ns/op 0 B/op 0 allocs/op
PASS
ok _/c_/.../.../Desktop 0.403s
Success: Benchmarks passed.
无意义的微基准测试产生无意义的结果。
The Go Programming Language Specification
int32 set of all signed 32-bit integers
(-2147483648 to 2147483647)
int64 set of all signed 64-bit integers
(-9223372036854775808 to 9223372036854775807)
Integer overflow
For signed integers, the operations +, -, *, /, and << may legally
overflow and the resulting value exists and is deterministically
defined by the signed integer representation, the operation, and its
operands. Overflow does not cause a run-time panic.
溢出!
package main
import (
"fmt"
"math"
"runtime"
"strconv"
"time"
)
func main() {
start := time.Now()
var x1 int32 // later change all int to int32 or int64
for i := int32(0); i <= int32(1000000000); i++ {
if int64(x1)+int64(i) > math.MaxInt32 {
fmt.Println("Overflow:", x1, "+", i, "=", x1+i)
break
}
x1 = x1 + i
}
t := time.Now()
elapsed := t.Sub(start)
fmt.Println(x1)
fmt.Println(elapsed)
fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
fmt.Println(strconv.IntSize)
}
游乐场:https://play.golang.org/p/bdhB4ABf7jY
输出:
Overflow: 2147450880 + 65536 = -2147450880
gc amd64 linux
64
我正在尝试找出有关性能的最佳实践。 我注意到为 for 循环指定整数类型可能会极大地影响性能(在我的例子中是 x2 倍)。
我的问题是,使用 int64 是否应该比使用 int32 慢得多,或者我的代码中遗漏了什么?
我使用的代码:
a.go
package main
import (
"fmt"
"time"
"runtime"
"strconv"
)
func main() {
start := time.Now()
var x1 int // later change all int to int32 or int64
for i := int(0); i <= int(1000000000); i++ {
x1 = x1 + i
}
t := time.Now()
elapsed := t.Sub(start)
fmt.Println(x1)
fmt.Println(elapsed)
fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
fmt.Println(strconv.IntSize)
}
x1 使用 int32 输出
C:\...>go build a.go
C:\...>a
-243309312
238.3333ms
gc amd64 windows
64
使用 int64 输出 x1
C:\...>go build a.go
C:\...>a
500000000500000000
467.7835ms
gc amd64 windows
64
更新
我尝试了@Giulio Micheloni 的建议并获得了更准确的基准。
goos: windows
goarch: amd64
BenchmarkInt64-12 1000000000 0.234 ns/op 0 B/op 0 allocs/op
PASS
ok _/c_/.../.../Desktop 0.402s
Success: Benchmarks passed.
goos: windows
goarch: amd64
BenchmarkInt32-12 1000000000 0.231 ns/op 0 B/op 0 allocs/op
PASS
ok _/c_/.../.../Desktop 0.403s
Success: Benchmarks passed.
无意义的微基准测试产生无意义的结果。
The Go Programming Language Specification
int32 set of all signed 32-bit integers (-2147483648 to 2147483647) int64 set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
Integer overflow
For signed integers, the operations +, -, *, /, and << may legally overflow and the resulting value exists and is deterministically defined by the signed integer representation, the operation, and its operands. Overflow does not cause a run-time panic.
溢出!
package main
import (
"fmt"
"math"
"runtime"
"strconv"
"time"
)
func main() {
start := time.Now()
var x1 int32 // later change all int to int32 or int64
for i := int32(0); i <= int32(1000000000); i++ {
if int64(x1)+int64(i) > math.MaxInt32 {
fmt.Println("Overflow:", x1, "+", i, "=", x1+i)
break
}
x1 = x1 + i
}
t := time.Now()
elapsed := t.Sub(start)
fmt.Println(x1)
fmt.Println(elapsed)
fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
fmt.Println(strconv.IntSize)
}
游乐场:https://play.golang.org/p/bdhB4ABf7jY
输出:
Overflow: 2147450880 + 65536 = -2147450880
gc amd64 linux
64