GOTO,它在设备上执行和运行时会影响性能吗?
在目标 C 中使用 GOTO 是一种好习惯还是使用它是不好的做法?
而且,什么时候使用 GOTO 语句是一个不错的选择?
谢谢。
GOTO,它在设备上执行和运行时会影响性能吗?
在目标 C 中使用 GOTO 是一种好习惯还是使用它是不好的做法?
而且,什么时候使用 GOTO 语句是一个不错的选择?
谢谢。
Agoto
只是一个跳跃,因此它对性能的影响几乎为零。这是一种不好的做法,因为它会损害代码的可读性;你几乎可以不用它。goto
在前面的问题中描述了一些有意义的使用案例,只需搜索 goto。
使用 go to 语句通常是一种不好的做法,尤其是在面向对象的语言中(您可以轻松地以 OO 方式实现相同的目的),但不是从性能的角度来看,而是从代码可读性的角度来看。 ..
BAD 和 GOOD 实践中没有任何内容,这取决于您的要求。如果你有相同的代码要执行,你可以说循环然后你可以使用goto
. 好吧,这是一个关于此的小例子,我认为它可以消除您的疑问。
声明任何label
名称,hello
然后label
您可以使用goto
如下语句调用它 -
hello:
NSLog(@"Print hello!");
goto hello;
这将打印“打印你好!” 一次又一次。
不影响性能,只是为了良好的结构和可读性,这是专业编程的重要特征。但有时,在循环太深的情况下,使用 goto 可能有助于缓解复杂性,但您想在触发某些条件时跳出。即便如此,也可以通过其他方式避免。
原则上,只需存在于函数中goto
即可影响性能。
goto
性能差异几乎总是不明显的,除了会稍微扰乱优化器并影响性能之外,还有很多事情。但是,如果您有兴趣,可以检查发出的代码是否存在差异。
在 goto[*] 的源和目标中,相同的寄存器必须用于相同的事情,这是发出代码的基本要求。这限制了编译器优化代码时的寄存器分配。这样的约束可能根本没有影响,它们可能会减慢速度或导致发出额外的代码。如果他们加快了速度,那只能是偶然的,因为编译器的启发式方法在应用于无约束版本时实际上是不正确的。
对于计算的 goto(GNU 扩展),效果可能更明显,您可以在其中将标签存储在变量中并转到变量。在这种情况下,每个可能的目标都必须与每个可能的源共享一个寄存器状态。
(通常)不会对性能产生影响的是goto
块的开始或结束与等效的break
or continue
or else
。这对优化器来说都是一样的:编译器将你的代码分解成所谓的“基本块”,它们之间有跳转和条件跳转。它通常不关心跳转的原因是否为 a goto
,无论哪种情况,它都必须正确获取寄存器状态。这就是为什么几乎任何编程结构都可以被只考虑发出指令的人描述为“变相的 goto”。
[*] 更准确地说——在 goto 处可能有一个隐式的 zap,这意味着一些寄存器在源处用于一件事,而在目标处根本不使用。但是您不能拥有一些目标期望包含特定值(如变量的当前值)而源不包含特定值的寄存器。因此,如果之前是这种情况,然后您添加了 goto,则目标需要停止期待它,或者源需要将它放在那里。通常,任何一个都需要额外的代码来在寄存器和堆栈之间混洗值。