Я не особо разбираюсь во внутренностях оптимизации компилятора и 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 в этот процесс.
Кроме того, есть ли какие-либо типичные случаи оптимизации, о которых мне следует знать при создании модульных тестов?
Большое спасибо!