我对编译器和JIT优化的内部知识不是很了解,但是我通常尝试使用“常识”来猜测可以优化的内容和不能优化的东西。所以今天我在写一个简单的单元测试方法:
@Test // [Test] in C#
public void testDefaultConstructor() {
new MyObject();
}
我实际上只需要这种方法。它检查默认构造函数是否存在并且可以正常运行。
但是后来我开始考虑编译器/ JIT优化的效果。编译器/ JIT是否可以通过new MyObject();
完全消除该语句来优化此方法?当然,将需要确定调用图对其他对象没有副作用,这是仅构造对象内部状态的普通构造函数的典型情况。
我假设只有JIT才能执行这种优化。这可能意味着我不必担心,因为测试方法仅执行一次。我的假设正确吗?
不过,我正在尝试考虑一般主题。当我考虑如何防止此方法被优化时,我以为可以assertTrue(new MyObject().toString() != null)
,但这在很大程度上取决于该toString()
方法的实际实现,即使如此,JIT仍可以确定该toString()
方法始终返回非空字符串(例如(如果实际上Object.toString()
被调用),从而优化整个分支。所以这种方式行不通。
我知道在C#中可以使用[MethodImpl(MethodImplOptions.NoOptimization)]
,但这并不是我真正想要的。我希望找到一种(独立于语言的)方式来确保我的代码的某些特定部分将按我的预期实际运行,而不会干扰JIT。
此外,在创建单元测试时是否应该注意一些典型的优化案例?
非常感谢!
不用担心 不允许对可能对您的系统产生影响的任何事情进行优化(速度除外)。如果您新建了一个对象,则代码被调用,内存被分配,它就可以工作。
如果您使用if(false)保护它(其中false是最终的),则可以将其完全从系统中进行优化,然后它可以检测到该方法没有执行任何操作并优化IT(理论上)。
编辑:顺便说一句,它也可以足够聪明地确定此方法:
newIfTrue(boolean b) {
if(b)
new ThisClass();
}
如果b为假,将始终不执行任何操作,并最终弄清代码B中的某一点始终为假,并从该代码中完全编译该例程。
在这里,JIT可以完成任何非托管语言几乎不可能完成的工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句