是否存在针对goto的性能原因?

时间:2012-09-21 06:55:54

标签: iphone objective-c ios c ipad

GOTO,它在设备上执行并运行时会影响性能吗?

在目标C中使用GOTO是一种好习惯还是使用它是不好的做法?

而且,何时使用GOTO语句是一个不错的选择?

感谢。

5 个答案:

答案 0 :(得分:5)

goto只是一个跳跃,因此它对性能的影响几乎为零。这是一种不好的做法,因为它会损害代码的可读性;你几乎可以没有它。在以前的问题中描述了使用goto有意义的一些案例,仅search for goto

答案 1 :(得分:2)

使用go语句通常是一种不好的做法,特别是在面向对象的语言中(您可以轻松地以OO方式实现相同的目的),但不是从性能的角度而是从代码可读性点观点...

答案 2 :(得分:1)

BAD和GOOD练习中没有任何内容符合您的要求。 如果你有相同的代码,你可以说循环,那么你可以使用goto。那么这里有一个小例子,我认为这会让你明白疑问。

声明任何label名称,此处hellolabel,然后您可以使用goto语句调用它 -

hello:
    NSLog(@"Print hello!");
    goto hello;

这会打印'打印你好!'一次又一次。

答案 3 :(得分:1)

不影响性能,只是为了获得良好的结构和可读性,这是专业编程的重要特征。但有时候,在循环太深的情况下使用goto可能有助于减轻复杂性,但是当你触发某些条件时你想要跳出来。即便如此,也可以通过其他方式避免。

答案 4 :(得分:1)

原则上goto 可以仅仅通过出现在函数中来影响性能。

性能差异几乎总是不明显的,除goto之外还有很多其他因素可能会略微扰乱优化器并影响性能。但是,如果您感兴趣,可以检查发出的差异代码。

在发出的代码中,基本要求必须在goto [*]的源和目标处使用相同的寄存器。当编译器优化代码时,这会限制寄存器分配。这些约束可能根本没有任何影响,它们可能会减慢速度或导致发出额外的代码。如果他们加快速度,那只能是偶然的,因为当应用于无约束版本时,编译器的启发式实际上是不正确的。

对于计算的goto(GNU扩展),效果可能更明显,您可以在变量中存储标签并转到变量。在这种情况下,每个可能的目标都必须与每个可能的源共享一个寄存器状态。

(通常)对性能产生影响的是goto块的开头或结尾与等效的breakcontinueelse。它与优化器完全相同:编译器将代码分解为所谓的“基本块”,它们之间有跳转和条件跳转。它通常不关心跳转的原因是否为goto,并且无论如何都必须使寄存器状态正确。这就是为什么几乎任何编程结构都可以被一个只考虑发出指令的人描述为“伪装成goto”。

[*]更精确一点 - 在goto上可能存在隐式zap,这意味着某些寄存器在源处用于一件事并且在目标处根本不使用。但是你不能有一些目标期望包含特定值的寄存器(比如变量的当前值)而源不会。因此,如果之前是这种情况,然后添加goto,则目标需要停止预期,或者源需要将其放在那里。通常,任何一个都需要额外的代码来在寄存器和堆栈之间混洗值。