Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
598 views
in Technique[技术] by (71.8m points)

performance - 使用int64而不是int32时,for循环性能要慢得多(For loop performance much slower when using int64 instead of int32)

I am trying to figure out the best practices regarding performance.

(我正在尝试找出有关性能的最佳做法。)

I have noticed that specifying integer types for a for-loop could effect the performance drastically (x2 times in my case).

(我注意到为for循环指定整数类型可能会极大地影响性能(在我的情况下为x2倍)。)

My question is, is it supposed to be that using the int64 would be much slower than using int32 or I am missing something in my code?

(我的问题是,是否应该认为使用int64比使用int32慢得多,或者我的代码中缺少某些内容?)

The code I am using:

(我正在使用的代码:)

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)
}

Output using int32 for x1

(使用int32输出x1)

C:...>go build a.go
C:...>a

-243309312
238.3333ms
gc amd64 windows
64

Output using int64 for x1

(使用x1的int64输出)

C:...>go build a.go
C:...>a

500000000500000000
467.7835ms
gc amd64 windows
64

Update

(更新资料)

I tried @Giulio Micheloni suggestion and got more accurate benchmark.

(我尝试了@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.
  ask by Kingindanord translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Meaningless microbenchmarks produce meaningless results.

(毫无意义的微基准测试将产生毫无意义的结果。)


The Go Programming Language Specification

(Go编程语言规范)

Numeric types

(数值类型)

 int32 set of all signed 32-bit integers (-2147483648 to 2147483647) int64 set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) 

Arithmetic operators

(算术运算符)

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.

(溢出不会引起运行时恐慌。)


Overflow!

(溢出!)

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)
}

Playground: https://play.golang.org/p/bdhB4ABf7jY

(游乐场: https : //play.golang.org/p/bdhB4ABf7jY)

Output:

(输出:)

Overflow: 2147450880 + 65536 = -2147450880
gc amd64 linux
64

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...