如何编写(测试)编译器/ JIT无法优化的代码?

Hosam Aly:

我对编译器和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。

此外,在创建单元测试时是否应该注意一些典型的优化案例?

非常感谢!

比尔K:

不用担心 不允许对可能对您的系统产生影响的任何事情进行优化(速度除外)。如果您新建了一个对象,则代码被调用,内存被分配,它就可以工作。

如果您使用if(false)保护它(其中false是最终的),则可以将其完全从系统中进行优化,然后它可以检测到该方法没有执行任何操作并优化IT(理论上)。

编辑:顺便说一句,它也可以足够聪明地确定此方法:

newIfTrue(boolean b) {
    if(b)
        new ThisClass();
}

如果b为假,将始终不执行任何操作,并最终弄清代码B中的某一点始终为假,并从该代码中完全编译该例程。

在这里,JIT可以完成任何非托管语言几乎不可能完成的工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章