Почему CLR .NET не выполняет короче много того что должны оптимизирующие компиляторы выполнять. Оптимизацию циклов, прочие преобразования
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
static int Sum1(int[] arr,int n)
{
int s = 0;
for (int i = 0; i < arr.Length; i++)
{
if(i<n) // или вообще вот так if(i==n) что по идеи цикл должно убирать
s += arr[i];
}
return s;
}
// или такой еще метод
static int Sum1(int[] arr,int n)
{
int s = 0;
for (int i = 0; i < arr.Length; i++)
{
if(i<n)
s += arr[i];
else(i>n)
s-=arr[i];
}
// почему такой цикл на 2 цикла не преобразуется.
for (int i = 0; i < n; i++) s += arr[i];
for (int i = n; i < len; i++) s-=arr[i];
return s;
}
// или вот
for(int i=0;i<len;i++)
if(i%2==0) f1();
else f2();
// еще заметил для функции выше, которая точно такая как пример выше помимо этого
// не убирает else
for(int i=0;i<len;i++)
if(i%2==0) {
f1();
continue;
}
f2();
Почему такой код не оптимизируется в рамках оптимизации циклов?
Я еще заметил циклы не разматываются.
Я думал, что такой код невозможно написать, но примерно такое часто встречается, если смотреть в глубь калбеков. Когда допустим внешняя функция по параметру вызывает функцию, а внутренняя еще раз этот параметр проверяет, к примеру проверки на NullPointer.
И допустим такая функция из 2 мест вызывается, и в 1-ом месте, уже это параметр проверен.
И такое прям часто, и решения как правило добавить параметр, или отдельную функцию написать. Но с бибилотечными функциями так не получится, хотя убрать из них лишние проверки, кажется не сложная задача при компиляции.
Но если так подумать, то вроде как сам компилятор может же сам создать копию функции, с другим кодом, убрав лишние проверки.