bool类型与int数组的性能比较

huangapple go评论100阅读模式
英文:

Performance of bool vs int array

问题

在使用Go语言编写一些简单代码时,我注意到使用布尔数组而不是整数数组(整数数组只使用0/1值)可以显著提高速度。

  • funcUsingBool - 1.397秒
  • funcUsingInt - 1.996秒

我本来期望它们的性能相同,因为在机器级别上没有原生的布尔类型,所以我本来期望编译器生成类似的汇编代码。

由于差异相当大,我对这个结果的有效性表示怀疑。

我使用命令"go build filename.go"进行构建,但我不确定相当于gcc的"-O3"的等效标志是什么。

func funcUsingBool(n int) int {
    if n < 1 { return 0 }

    notPrime := make([]bool, n+1)
    count := 1
    for i := 3; i < n; i = i + 2 {
        if notPrime[i] { continue }
        count++
        k := 2 * i
        for k <= n {
            notPrime[k] = true
            k += i
        }
    }
    return count
}

func funcUsingInt(n int) int {
    if n < 1 { return 0}

    notPrime := make([]int, n+1)
    count := 1
    for i := 3; i < n; i = i + 2 {
        if notPrime[i] == 1 { continue }
        count++
        k := 2 * i
        for k <= n {
            notPrime[k] = 1
            k += i
        }
    }
    return count
}
英文:

While playing with some simple code in Go I noticed that using a bool array instead of int array(which uses only values of 0/1) has a pretty significant speed-up.

  • funcUsingBool - 1.397s
  • funcUsingInt - 1.996s

I would have expected both of them to give the same performance since there isn't a native bool type at machine level, so I would have expected the compiler to generate similar assembly code.

Since the difference is pretty big, I'm skeptical on the validity of this result.

I'm building using the command "go build filename.go", but I'm not sure what's the equivalent flag of gcc's "-O3".

func funcUsingBool(n int) int {
	if n &lt; 1 { return 0 }

	notPrime := make([]bool, n+1)
	count := 1
	for i := 3; i &lt; n; i = i + 2 {
		if notPrime[i] { continue }
		count++
		k := 2 * i
		for k &lt;= n {
			notPrime[k] = true
			k += i
		}
	}
	return count
}

func funcUsingInt(n int) int {
	if n &lt; 1 { return 0}

	notPrime := make([]int, n+1)
	count := 1
	for i := 3; i &lt; n; i = i + 2 {
		if notPrime[i] == 1 { continue }
		count++
		k := 2 * i
		for k &lt;= n {
			notPrime[k] = 1
			k += i
		}
	}
	return count
}

答案1

得分: 4

查看汇编输出(go run -gcflags '-S' test.go),有一些差异:

Bool(布尔型):

0x0075 00117 (test.go:11)	MOVBLZX	(AX)(BX*1), DI
0x0079 00121 (test.go:11)	TESTB	DIB, DIB

Int(整型):

0x0075 00117 (test.go:28)	MOVQ	(AX)(BX*8), DI
0x0079 00121 (test.go:28)	CMPQ	DI, $1

Byte/uint8(字节/无符号整型):

0x0075 00117 (test.go:28)	MOVBLZX	(AX)(BX*1), DI
0x0079 00121 (test.go:28)	CMPB	DIB, $1

对我来说,其余的汇编代码在Go 1.8.*上几乎相同。

所以:1)数据类型的大小不同 2)操作不同

英文:

Looking at the assembly output (go run -gcflags &#39;-S&#39; test.go) there is some difference:

Bool:

0x0075 00117 (test.go:11)	MOVBLZX	(AX)(BX*1), DI
0x0079 00121 (test.go:11)	TESTB	DIB, DIB

Int:

0x0075 00117 (test.go:28)	MOVQ	(AX)(BX*8), DI
0x0079 00121 (test.go:28)	CMPQ	DI, $1

Byte/uint8:

0x0075 00117 (test.go:28)	MOVBLZX	(AX)(BX*1), DI
0x0079 00121 (test.go:28)	CMPB	DIB, $1

The rest of the assembly is near-identical for me on Go 1.8.*.

So: 1) data types are sized different 2) operations are different

huangapple
  • 本文由 发表于 2017年6月30日 22:15:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/44848595.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定