Отключение проверки выхода за границы массива
От: VladCore  
Дата: 21.09.20 03:01
Оценка: 5 (1)
Кто помнит, в обоих ли случаях JIT отключает проверку на выход за границы массива, или только в первом?

первый
for(int i=0; i<arr.Length; i++) {
  DoSomething(arr[i]);
}


второй
for(int i=0, len=arr.Length; i<len; i++) {
  DoSomething(arr[i]);
}


arr — массив одномерный в обоих случаях
Re: Отключение проверки выхода за границы массива
От: rameel https://github.com/rsdn/CodeJam
Дата: 21.09.20 04:06
Оценка: 84 (3)
Здравствуйте, VladCore, Вы писали:

VC>Кто помнит, в обоих ли случаях JIT отключает проверку на выход за границы массива, или только в первом?

VC>arr — массив одномерный в обоих случаях

Зависит от рантайма. Для последних (Core и NET FW 4.8 x64) разницы никакой нет, будет сгенерирован один и тот же код — проверки на выход за границы будут устранены. Для NET FW 4.8 x86 во втором варианте оптимизация уже не работает, соответственно проверки устранены уже не будут.

Все это справедливо только, если работаешь с локальной переменной или аргументом метода. В этом случае, джит уверен, что никто не изменит ссылку из вне метода, в остальном случае — гарантий нет, и джит вставит проверки на выход за границы массива
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Отредактировано 21.09.2020 4:09 rameel . Предыдущая версия .
Re: Отключение проверки выхода за границы массива
От: Danchik Украина  
Дата: 21.09.20 06:19
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>Кто помнит, в обоих ли случаях JIT отключает проверку на выход за границы массива, или только в первом?


[Skip]

VC>arr — массив одномерный в обоих случаях


Похоже одинаково: https://sharplab.io/#gist:96b004a235bfa4674d2dea21c7d8d17b
Re[2]: Отключение проверки выхода за границы массива
От: rameel https://github.com/rsdn/CodeJam
Дата: 21.09.20 06:53
Оценка: 16 (2)
Здравствуйте, Danchik, Вы писали:

D>Похоже одинаково: https://sharplab.io/#gist:96b004a235bfa4674d2dea21c7d8d17b


Для Core без разницы, для NET FW — 64 бита тоже разницы нет, а вот для 32 уже не так

https://sharplab.io/#v2:EYLgdgpgLgZgHgGiiAhgZwLYB8
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[2]: Отключение проверки выхода за границы массива
От: VladCore  
Дата: 21.09.20 16:52
Оценка:
Здравствуйте, rameel, Вы писали:

VC>>Кто помнит, в обоих ли случаях JIT отключает проверку на выход за границы массива, или только в первом?

VC>>arr — массив одномерный в обоих случаях

R>Зависит от рантайма. Для последних (Core и NET FW 4.8 x64) разницы никакой нет, будет сгенерирован один и тот же код — проверки на выход за границы будут устранены. Для NET FW 4.8 x86 во втором варианте оптимизация уже не работает, соответственно проверки устранены уже не будут.


R>Все это справедливо только, если работаешь с локальной переменной или аргументом метода. В этом случае, джит уверен, что никто не изменит ссылку из вне метода, в остальном случае — гарантий нет, и джит вставит проверки на выход за границы массива


а JIT только про массивы знает или другие коллекции с неизменной длиной тоже оптимизирует на проверку выхода за границы?
Re[3]: Отключение проверки выхода за границы массива
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.09.20 17:19
Оценка: 16 (2) +1
Здравствуйте, VladCore, Вы писали:
VC>а JIT только про массивы знает или другие коллекции с неизменной длиной тоже оптимизирует на проверку выхода за границы?
Только про массивы и Span<T>/ReadOnlySpan<T>.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Отключение проверки выхода за границы массива
От: Sharov Россия  
Дата: 05.01.21 19:13
Оценка:
Здравствуйте, rameel, Вы писали:

R>Здравствуйте, VladCore, Вы писали:


VC>>Кто помнит, в обоих ли случаях JIT отключает проверку на выход за границы массива, или только в первом?

VC>>arr — массив одномерный в обоих случаях

R>Зависит от рантайма. Для последних (Core и NET FW 4.8 x64) разницы никакой нет, будет сгенерирован один и тот же код — проверки на выход за границы будут устранены. Для NET FW 4.8 x86 во втором варианте оптимизация уже не работает, соответственно проверки устранены уже не будут.


А почему будет такая разница в сгенерированно коде?

R>Все это справедливо только, если работаешь с локальной переменной или аргументом метода. В этом случае, джит уверен, что никто не изменит ссылку из вне метода, в остальном случае — гарантий нет, и джит вставит проверки на выход за границы массива


А как jit убедиться, что никто не изменит аргумент в вызывающем коде? Всяческая многопоточность и т.д.
Кодом людям нужно помогать!
Re[3]: Отключение проверки выхода за границы массива
От: rameel https://github.com/rsdn/CodeJam
Дата: 06.01.21 14:25
Оценка: 6 (1) +1
Здравствуйте, Sharov, Вы писали:

S>А почему будет такая разница в сгенерированно коде?


.NET Framework уже не развивают, может бэкпортят что-то из корки. Плюс, в .NET Framework были разные бекенды для x86 и x64, отсюда и разница в реализованных оптимизациях

R>>Все это справедливо только, если работаешь с локальной переменной или аргументом метода. В этом случае, джит уверен, что никто не изменит ссылку из вне метода, в остальном случае — гарантий нет, и джит вставит проверки на выход за границы массива


S>А как jit убедиться, что никто не изменит аргумент в вызывающем коде? Всяческая многопоточность и т.д.


В данном случае речь идет о массивах, а длина массива не меняется, а ссылка на массив в переданном аргументе поменяться не может
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[3]: Отключение проверки выхода за границы массива
От: alexzzzz  
Дата: 11.01.21 10:09
Оценка: 5 (1)
Здравствуйте, Sharov, Вы писали:

R>>Все это справедливо только, если работаешь с локальной переменной или аргументом метода. В этом случае, джит уверен, что никто не изменит ссылку из вне метода, в остальном случае — гарантий нет, и джит вставит проверки на выход за границы массива


S>А как jit убедиться, что никто не изменит аргумент в вызывающем коде? Всяческая многопоточность и т.д.


Длина массива не может меняться. С вариантом, когда массив локальный, ведь тоже не всё здорово:
void Foo()
{
    var a = new int[10];
    Bar(a);
    for (int i = 0; i < a.Length; i++)
    {
        ...
    }
}


Внутри Bar() ссылка на массив могла где-то дополнительно сохраниться и успеть прочитаться другими потоками, которые могут начать менять содержимое массива одновременно с циклом внутри Foo().
Отредактировано 11.01.2021 10:10 alexzzzz . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.