Короче, сижу себе такой, никого не трогаю, пишу маленькую программку под андроид, на яве значит.
И там у меня должен получится вот такой фрагмент кода:
while (i < raw_data.length()) i = parseName(raw_data, i+1, j++);
Собственно, анализирую и разбираю строку raw_data. По идее, оптимизатор должен сам вынести из цикла инварианты. Но не факт, тем более что вызывается метод, в котором вдруг что-нибудь со строкой происходит.
Поэтому "оптимизирую" ручками. Ну вот люблю я какую-нибудь совершенно не нужную мелочь соптимизировать. )
int k = raw_data.length();
while (i < k)
i = parseName(raw_data, i+1, j++);
И ничего бы я так и не заметил, если бы не потребовалась отладка. А под отладкой я вижу, что перебираются не только две последние строчки цикла, но и первая, которую я специально из цикла вынес, для оптимизации.
Не знаю, чем это объяснить. Может, очень глубокой оптимизацией? Скорее всего длина строки хранится в поле объекта, оптимизатор пишет эффективное обращение к ней напрямую, без вызова метода, а переменную k вообще не использует? Зачем тогда в отладчике показывает посещение первой строчки?
Но это предположение не верно. В ходе отладке выясняется, где находится ошибка. Правильный код должен выглядеть вот так:
int k = raw_data.length()-1;
while (i < k)
i = parseName(raw_data, i+1, j++);
И в этом случае первая строка кода тоже попадает в цикл!
Так что дело тут не в оптимизации, а, похоже, в параноидальной заботе о корректности кода со стороны Java-компилятора. А вдруг в методе parseName что-нибудь вытворят с raw_data? Поэтому загоним инвариант обратно в цикл.
Но, уважаемые разработчки Java, я специально вынес длину строки в отдельную переменную, что бы не делать лишних вычислений, потому что уверен в том, что parseName raw_data не меняет!
Вот такие чудеса! Или я просто Java готовить не умею?
Эти вольности опимизации совершенно точно не допустимы в Java, к тому же в дебаге JVM работает в режиме интерпретатора и код выполняется вообще как есть...
ОтветитьУдалитьЧто могло быть:
1. Вы дебажите не совсем те исходники что компилировались, может там препроцессор какой-нибудь который сместил все строчки?
2. Какой-то хитрый баг в Andoid Studio.
Я не знаком с Андроид, но так точно быть не должно :)
П.С. В java есть javap утелитка, она может показать в человеческом виде что внутри class файла.
Как-то не совсем точно я изложил свои мысли :)
УдалитьВ Java javac вообще практически ничего не оптимизирует, и только в рантайме jvm выполняет оптимизацию, если не в дебаггере. Теоретически она наверное может решить запихать выражение внутрь цикла, если решит что это будет работать быстрее, но только если это не изменит семантику...
Как работает APT я не знаю, но наверное примерно так же :)
1. Я тоже так думал... Но тогда вроде все остальные строчки тоже как бы должны сместиться в методе, но вроде нет такого. Как будет время попробую разобраться.
Удалить2. Все может быть. Отлаживаюсь прямо на устройстве, а не на эмуляторе.
В общем, непонятная странность.
Нда... Похоже, это я окарал.
УдалитьЗапустил тут намедни Android Studio, сделал Rebuild, а затем пришло суровое, глобальное обновление. После этого отладчик ведет себя как надо. Так что да, скорее всего сбились строчки.
Впрочем, в Delphi, если сбились строчки в отладчике, достаточно было перекомпилировать проект. В Studio же компиляция не помогла. Видимо, надо делать все же Rebuild. Или ждать глобального обновления? )