Сообщение Re[49]: «Собаку съел» от 20.01.2017 16:14
Изменено 20.01.2017 16:23 Serginio1
Re[49]: «Собаку съел»
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, samius, Вы писали:
S>>>Т.е. если компаратор заранее известен, то никакого отношения к инлайну дженерикового компаратора это не имеет.
S>> Угу, а как же шаблоны то инлайнят функции при специализации, если компаратор не известен
S>В момент специализации шаблона он известен.
S>>Еще раз
S>>
S>> Здесь как ты видишь дженерик метод Func<TSource, bool> predicate
S>>При этом автоматически выводится тип.
S>Дженерик метод, точнее делегат и выводящийся тип я вижу. Я не вижу здесь дженерикового компаратора. Его в этом примере нет, изначально есть лишь оператор сравнения для Int32. И в процессе инлайна Where и т.п., вызов оператора сравнения Int32 остается самим же собой. Т.е. с ним абсолютно ничего не происходит.
Изначально происходит специализация как и в шаблонах C++
а Func<TSource, bool> predicate учавствует в дженерик коде .
S>>>Инлайнится Where, Select и Sum, функция, принимающая целый x и сравнивающая с q, функция, добавляющая целому 3. Но никак не компаратор и оператор сложения. Параметрически полиморфны здесь Where и Select, но не компаратор, сложение и Sum.
S>> Еще раз, нет никаких особых препятствий для инлайнинга сомпараторов при специализации как это делается в C++.
S>Препятствий-то нет, но и инлайнинга тоже нет.
А откуда ты з-наешь?
S>>При этом в том же Net Native как раз это и происходит.
S>Можно ссылку? Еще раз уточню, я ожидаю увидеть автоматический разворот обобщенного компаратора Compare<T>(T, T) в специальный для типа T. Именно это я подразумеваю под инлайном дженерикового компаратора.
Вот смотри исходники
https://github.com/Microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs
А вот как это разворачивается
Optimising LINQ
roslyn-linq-rewrite
Так Func<TSource, bool> predicate
это и есть компаратор. Он и разворачивается.
S>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, samius, Вы писали:
S>>>Т.е. если компаратор заранее известен, то никакого отношения к инлайну дженерикового компаратора это не имеет.
S>> Угу, а как же шаблоны то инлайнят функции при специализации, если компаратор не известен
S>В момент специализации шаблона он известен.
S>>Еще раз
S>>
S>>public static IEnumerable<TSource> Where<TSource>(
S>> this IEnumerable<TSource> source,
S>> Func<TSource, bool> predicate
S>>)
S>>
S>> Здесь как ты видишь дженерик метод Func<TSource, bool> predicate
S>>При этом автоматически выводится тип.
S>Дженерик метод, точнее делегат и выводящийся тип я вижу. Я не вижу здесь дженерикового компаратора. Его в этом примере нет, изначально есть лишь оператор сравнения для Int32. И в процессе инлайна Where и т.п., вызов оператора сравнения Int32 остается самим же собой. Т.е. с ним абсолютно ничего не происходит.
Изначально происходит специализация как и в шаблонах C++
а Func<TSource, bool> predicate учавствует в дженерик коде .
S>>>Инлайнится Where, Select и Sum, функция, принимающая целый x и сравнивающая с q, функция, добавляющая целому 3. Но никак не компаратор и оператор сложения. Параметрически полиморфны здесь Where и Select, но не компаратор, сложение и Sum.
S>> Еще раз, нет никаких особых препятствий для инлайнинга сомпараторов при специализации как это делается в C++.
S>Препятствий-то нет, но и инлайнинга тоже нет.
А откуда ты з-наешь?
S>>При этом в том же Net Native как раз это и происходит.
S>Можно ссылку? Еще раз уточню, я ожидаю увидеть автоматический разворот обобщенного компаратора Compare<T>(T, T) в специальный для типа T. Именно это я подразумеваю под инлайном дженерикового компаратора.
Вот смотри исходники
https://github.com/Microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs
А вот как это разворачивается
Optimising LINQ
roslyn-linq-rewrite
Так Func<TSource, bool> predicate
это и есть компаратор. Он и разворачивается.
Re[49]: «Собаку съел»
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, samius, Вы писали:
S>>>Т.е. если компаратор заранее известен, то никакого отношения к инлайну дженерикового компаратора это не имеет.
S>> Угу, а как же шаблоны то инлайнят функции при специализации, если компаратор не известен
S>В момент специализации шаблона он известен.
S>>Еще раз
S>>
S>> Здесь как ты видишь дженерик метод Func<TSource, bool> predicate
S>>При этом автоматически выводится тип.
S>Дженерик метод, точнее делегат и выводящийся тип я вижу. Я не вижу здесь дженерикового компаратора. Его в этом примере нет, изначально есть лишь оператор сравнения для Int32. И в процессе инлайна Where и т.п., вызов оператора сравнения Int32 остается самим же собой. Т.е. с ним абсолютно ничего не происходит.
Изначально происходит специализация как и в шаблонах C++
а Func<TSource, bool> predicate учавствует в дженерик коде .
S>>>Инлайнится Where, Select и Sum, функция, принимающая целый x и сравнивающая с q, функция, добавляющая целому 3. Но никак не компаратор и оператор сложения. Параметрически полиморфны здесь Where и Select, но не компаратор, сложение и Sum.
S>> Еще раз, нет никаких особых препятствий для инлайнинга сомпараторов при специализации как это делается в C++.
S>Препятствий-то нет, но и инлайнинга тоже нет.
А откуда ты з-наешь?
S>>При этом в том же Net Native как раз это и происходит.
S>Можно ссылку? Еще раз уточню, я ожидаю увидеть автоматический разворот обобщенного компаратора Compare<T>(T, T) в специальный для типа T. Именно это я подразумеваю под инлайном дженерикового компаратора.
Вот смотри исходники
https://github.com/Microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs
А вот как это разворачивается
Optimising LINQ
roslyn-linq-rewrite
Так Func<TSource, bool> predicate
это и есть компаратор. Он и разворачивается.
То есть
Прекрасно разворачивается
S>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, samius, Вы писали:
S>>>Т.е. если компаратор заранее известен, то никакого отношения к инлайну дженерикового компаратора это не имеет.
S>> Угу, а как же шаблоны то инлайнят функции при специализации, если компаратор не известен
S>В момент специализации шаблона он известен.
S>>Еще раз
S>>
S>>public static IEnumerable<TSource> Where<TSource>(
S>> this IEnumerable<TSource> source,
S>> Func<TSource, bool> predicate
S>>)
S>>
S>> Здесь как ты видишь дженерик метод Func<TSource, bool> predicate
S>>При этом автоматически выводится тип.
S>Дженерик метод, точнее делегат и выводящийся тип я вижу. Я не вижу здесь дженерикового компаратора. Его в этом примере нет, изначально есть лишь оператор сравнения для Int32. И в процессе инлайна Where и т.п., вызов оператора сравнения Int32 остается самим же собой. Т.е. с ним абсолютно ничего не происходит.
Изначально происходит специализация как и в шаблонах C++
а Func<TSource, bool> predicate учавствует в дженерик коде .
S>>>Инлайнится Where, Select и Sum, функция, принимающая целый x и сравнивающая с q, функция, добавляющая целому 3. Но никак не компаратор и оператор сложения. Параметрически полиморфны здесь Where и Select, но не компаратор, сложение и Sum.
S>> Еще раз, нет никаких особых препятствий для инлайнинга сомпараторов при специализации как это делается в C++.
S>Препятствий-то нет, но и инлайнинга тоже нет.
А откуда ты з-наешь?
S>>При этом в том же Net Native как раз это и происходит.
S>Можно ссылку? Еще раз уточню, я ожидаю увидеть автоматический разворот обобщенного компаратора Compare<T>(T, T) в специальный для типа T. Именно это я подразумеваю под инлайном дженерикового компаратора.
Вот смотри исходники
https://github.com/Microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs
А вот как это разворачивается
Optimising LINQ
roslyn-linq-rewrite
Так Func<TSource, bool> predicate
это и есть компаратор. Он и разворачивается.
То есть
while (enumerator.MoveNext()) {
TSource item = enumerator.Current;
if (predicate(item)) {
current = item;
return true;
}
}
Прекрасно разворачивается
Example input code
public int Method1()
{
var arr = new[] { 1, 2, 3, 4 };
var q = 2;
return arr.Where(x => x > q).Select(x => x + 3).Sum();
}
Allocations: input array, array enumerator, closure for q , Where delegate, Select delegate, Where enumerator, Select enumerator.
Decompiled output code
public int Method1()
{
int[] arr = new[] { 1, 2, 3, 4 };
int q = 2;
return this.Method1_ProceduralLinq1(arr, q);
}
private int Method1_ProceduralLinq1(int[] _linqitems, int q)
{
if (_linqitems == null) throw new ArgumentNullException();
int num = 0;
for (int i = 0; i < _linqitems.Length; i++)
{
int num2 = _linqitems[i];
if (num2 > q)
num += num2 + 3;
}
return num;
}