Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go编译器是否足够聪明,可以进行微优化?_Go - Fatal编程技术网

Go编译器是否足够聪明,可以进行微优化?

Go编译器是否足够聪明,可以进行微优化?,go,Go,我很好奇像这样使用微优化是否有意义 当a是整数时,a/2与a>>1 a*2vsa简短回答,是的,编译器优化了这些。 但是对于int和uint(以及任何有符号和无符号整数类型,如byte)来说,情况略有不同 在这两种情况下,都避免了乘法和除法指令,但对于无符号整数,它只是一条指令(对于有符号整数,则只有少量指令)。 这是因为您的语句对仅对无符号整数完全等效,而对有符号整数不完全等效 更长的回答: 采用以下简单程序: package main func main() {} func div2(

我很好奇像这样使用微优化是否有意义

  • 当a是整数时,
    a/2
    a>>1

  • a*2
    vs
    a简短回答,是的,编译器优化了这些。
    但是对于
    int
    uint
    (以及任何有符号和无符号整数类型,如
    byte
    )来说,情况略有不同

    在这两种情况下,都避免了乘法和除法指令,但对于无符号整数,它只是一条指令(对于有符号整数,则只有少量指令)。 这是因为您的语句对仅对无符号整数完全等效,而对有符号整数不完全等效

    更长的回答:

    采用以下简单程序:

    package main
    
    func main() {}
    
    func div2(a int) {
            b := a / 2
            c := a >> 1
            _, _ = b, c
    }
    
    func mul2(a int) {
            b := a * 2
            c := a << 1
            _, _ = b, c
    }
    
    func mod2(a int) {
            b := a % 2
            c := a & 1
            _, _ = b, c
    }
    
    这里,
    BX
    是参数,
    DX
    BX
    似乎是两个结果 (
    BX
    被重新用作结果之一)。 在这里,它们略有不同,但只有一些说明 (查看所示的源行号) 没有任何除法或乘法指令 (所以基本上也一样快)。 这种差异是由于算法移位和逻辑移位以及mod如何处理负值造成的

    您可以通过在程序中将
    int
    更改为
    uint
    来确认这一点,然后输出包含以下内容:

            0x0008 00008 (…/opt.go:18)       ANDQ    $1,CX
            0x000c 00012 (…/opt.go:19)       ANDQ    $1,BX
    
    i、 e.完全相同的说明。
    您给出的每个示例都是这样。

    对您来说很明显,但可能不是下一个处理代码的人:)难道不可能检查Go字节代码以查看编译器是否进行了任何优化吗?要确定发生了什么,您需要查看编译器输出,可能需要使用
    Go build-gcflags=“-s”
    。您尝试过任何基准测试吗?至少二十年来,这些类型的优化已经成为编译器的标准。编写有意义的代码,并让编译器进行优化。如果您遇到编译器无法处理的情况,请以道歉的形式写一条评论,说明您为什么要编写如此奇怪的代码。
    因为这些技术非常明显,甚至不是优化,更像是如何编写代码的偏好问题。
    如果这些技术非常明显,你为什么要在你的问题中进行并列比较?提示hintI真的不在乎。评论中压倒性的观点似乎与您的观点不一致。这里需要注意的是,编译器正确地识别了可以进行优化的情况,例如在无符号整数上,并避免了无法进行优化的情况,例如有符号整数,其中可能会移动符号位,这将是完全错误的。实际上,它不仅仅是“一两条指令”,但它没有“正常”数学运算中看到的
    DIVQ
    MULQ
    、或
    IMULQ
    ,正如塔德曼正确指出的那样,它们确实需要更长的时间才能完全正确地表示有符号整数。
            0x0008 00008 (…/opt.go:18)       ANDQ    $1,CX
            0x000c 00012 (…/opt.go:19)       ANDQ    $1,BX