Search code examples
c#java.netoptimizationjit

How do I write (test) code that will not be optimized by the compiler/JIT?


I don't really know much about the internals of compiler and JIT optimizations, but I usually try to use "common sense" to guess what could be optimized and what couldn't. So there I was writing a simple unit test method today:

@Test  // [Test] in C#
public void testDefaultConstructor() {
    new MyObject();
}

This method is actually all I need. It checks that the default constructor exists and runs without exceptions.

But then I started to think about the effect of compiler/JIT optimizations. Could the compiler/JIT optimize this method by eliminating the new MyObject(); statement completely? Of course, it would need to determine that the call graph does not have side effects to other objects, which is the typical case for a normal constructor that simply initializes the internal state of the object.

I presume that only the JIT would be allowed to perform such an optimization. This probably means that it's not something I should worry about, because the test method is being performed only once. Are my assumptions correct?

Nevertheless, I'm trying to think about the general subject. When I thought about how to prevent this method from being optimized, I thought I may assertTrue(new MyObject().toString() != null), but this is very dependent on the actual implementation of the toString() method, and even then, the JIT can determine that toString() method always returns a non-null string (e.g. if actually Object.toString() is being called), and thus optimize the whole branch. So this way wouldn't work.

I know that in C# I can use [MethodImpl(MethodImplOptions.NoOptimization)], but this is not what I'm actually looking for. I'm hoping to find a (language-independent) way of making sure that some specific part(s) of my code will actually run as I expect, without the JIT interfering in this process.

Additionally, are there any typical optimization cases I should be aware of when creating my unit tests?

Thanks a lot!


Solution

  • Don't worry about it. It's not allowed to ever optimize anything that can make a difference to your system (except for speed). If you new an object, code gets called, memory gets allocated, it HAS to work.

    If you had it protected by an if(false), where false is a final, it could be optimized out of the system completely, then it could detect that the method doesn't do anything and optimize IT out (in theory).

    Edit: by the way, it can also be smart enough to determine that this method:

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

    will always do nothing if b is false, and eventually figure out that at one point in your code B is always false and compile this routine out of that code completely.

    This is where the JIT can do stuff that's virtually impossible in any non-managed language.