Re[48]: benchmark
От: Evgeny.Panasyuk Россия  
Дата: 20.01.17 16:34
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>>>Тут тоже интересная тема, чем отличается для компилятора A a; a.f.();, от A* a; a->f(); , что сlang ,что gcc генерят в последнем случае косвенный вызов.

EP>>В последнем случае вообще UB.
_>Я создание объекта для краткости просто опустил

Это ключевой момент (помимо включённых оптимизаций) — чтобы заинлайнить компилятор должен видеть какого типа объект по указателю объект.
В случае A a; a.f(); — тип объекта неизменен, поэтому и элементарно инлайнится, даже если между созданием и использованием будет много "непрозрачного" кода использующего этот объект.
Кстати, в C++11 появился final — он тоже помогает инлайнингу.
Re[38]: Visual C# vs C++. Надо сравнить перспективы.
От: Klikujiskaaan КНДР  
Дата: 20.01.17 16:46
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ещё один сишарпист принёс говнеца в тему — да уж, бытие определяет их сознание


Ну, во первых: это ты с порваной жо бегаешь из темы в тему, демонстрируя свои комплексы С++неполноценности
Во вторых: я не пишу на шарпе.
Re[39]: Visual C# vs C++. Надо сравнить перспективы.
От: Evgeny.Panasyuk Россия  
Дата: 20.01.17 17:08
Оценка:
Здравствуйте, Klikujiskaaan, Вы писали:

EP>>Ещё один сишарпист принёс говнеца в тему — да уж, бытие определяет их сознание

K>Ну, во первых: это ты с порваной жо бегаешь из темы в тему,

Я уже понял что у тебя проблемы с жо, и фиксация на теме "троганья всякого", но не надо здесь об этом кричать — это оффтопик, спасибо.

K>демонстрируя свои комплексы С++неполноценности


Какие комплексы? Например? Без всяких комплексов использую другие языки, в том числе C#
Re[50]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.01.17 18:03
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

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


S>>> Еще раз, нет никаких особых препятствий для инлайнинга сомпараторов при специализации как это делается в C++.

S>>Препятствий-то нет, но и инлайнинга тоже нет.

S> А откуда ты з-наешь?

Вижу по примеру.

S>Вот смотри исходники


S>https://github.com/Microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs


S> А вот как это разворачивается


S>Optimising LINQ


S>roslyn-linq-rewrite

Я ровно об этом и пишу, что разворачивается все что угодно, но не компаратор.


S> Так Func<TSource, bool> predicate

S> это и есть компаратор. Он и разворачивается.
То есть ты называешь компаратором предикат, потому мы и не можем понять друг друга.

S> То есть


То есть в этом примере отсутствует как класс обобщенный параметрически полиморфный компаратор. За него ad hoc полиморфный оператор сравнения для Int32, подставляемый компилятором (уже сколько лет) по выведенному типу T для метода Where исходя из типа первого аргумента. И оптимизация линка ровно ничего с вызовом оператора сравнения Int32 не делает, оставляет его как есть.
Re[51]: «Собаку съел»
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 20.01.17 18:37
Оценка:
Здравствуйте, samius, Вы писали:

S>> Так Func<TSource, bool> predicate

S>> это и есть компаратор. Он и разворачивается.
S>То есть ты называешь компаратором предикат, потому мы и не можем понять друг друга.

В .Net это называется дженерик метод.
Чеи он отличается от компаратора?
S>> То есть

S>То есть в этом примере отсутствует как класс обобщенный параметрически полиморфный компаратор. За него ad hoc полиморфный оператор сравнения для Int32, подставляемый компилятором (уже сколько лет) по выведенному типу T для метода Where исходя из типа первого аргумента. И оптимизация линка ровно ничего с вызовом оператора сравнения Int32 не делает, оставляет его как есть.


Еще раз при специализации шаблона будет подставляться код перегрузки оператора. Тоже самое.
Это та же кодогенерация. Просто в .Net можно делать оптимизацию при компиляции в CIL, а затем из CIL в машинный код.
Аналог С++ это аналог LLVM

Еще раз Func<TSource, bool>

TSource это дженерик параметр и никакой не инт

Внутри дженерик метода он вызывается.
То есть по твоему predicate(item)) это не дженерик метод?

while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate(item)) {
                                current = item;
                                return true;
                            }
                        }



Другое дело, что разворачивается не один оператор, а сразу несколько в одном цикле.
И для Linq они оптимизированы.
И по большому счету Linq применяется больше всех дженериков.
Еще раз повторю нет проблем проинлайнить методы интерфейса, если известно статически его определение.
Это тоже само что и перегрузка операторов. Все исходники для этого есть.

Вот когда ваши шаблоны будут так разворачиваться тогда может ...
и солнце б утром не вставало, когда бы не было меня
Re[52]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.01.17 21:09
Оценка: +2
Здравствуйте, Serginio1, Вы писали:

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


S>>> Так Func<TSource, bool> predicate

S>>> это и есть компаратор. Он и разворачивается.
S>>То есть ты называешь компаратором предикат, потому мы и не можем понять друг друга.

S> В .Net это называется дженерик метод.

Не согласен. В дотнете это называется дженерик делегат.

S>Чеи он отличается от компаратора?

Под компаратором я понимаю нечто (метод или делегат), что принимает два аргумента и возвращает признак превосходства значения одного аргумента над значением другого. Т.е. отличия как минимум в сигнатуре, в семантике использования.
S>>> То есть

S> Еще раз при специализации шаблона будет подставляться код перегрузки оператора. Тоже самое.

S> Это та же кодогенерация. Просто в .Net можно делать оптимизацию при компиляции в CIL, а затем из CIL в машинный код.
S>Аналог С++ это аналог LLVM

Я тут вовсе не точу за C++.

S>Еще раз Func<TSource, bool>


S>TSource это дженерик параметр и никакой не инт

но это дженерик параметр метода Where. А метод, сравнивающий x и q — внезапно вовсе не дженериковый.
Вот как мне его показывает ILSpy:
Исходник
       where (x >= lo) && (x <= hi)

результат в ILSpy
// ClassLibrary2.Class1.<>c__DisplayClass1_0
internal bool <Scale>b__0(int x)
{
    return x >= this.lo && x <= this.hi;
}

Увы, дженерика не было.
В IL
.method assembly hidebysig 
    instance bool '<Scale>b__0' (
        int32 x
    ) cil managed

Т.е. угловые скобки здесь — часть сгенерированного имени, но не признак дженерика.

S>Внутри дженерик метода он вызывается.

S> То есть по твоему predicate(item)) это не дженерик метод?
По-моему — нет. И по ILSpy-евскому тоже. Ему можно верить.

S> Другое дело, что разворачивается не один оператор, а сразу несколько в одном цикле.

S>И для Linq они оптимизированы.
S> И по большому счету Linq применяется больше всех дженериков.
S>Еще раз повторю нет проблем проинлайнить методы интерфейса, если известно статически его определение.
Теоретически — нет. Проблема в том, что примера, который бы это демонстрировал, я не вижу.

Я знаю про возможность заинлайнить метод интерфейса, если реализовать его структурой, подать структуру через дженерик аргумент с констрейнтом (и тогда, может быть заинлайнится).
Foo<T, TComparer>(...) where TComparer : IComparer<T>

Но я в LINQ не вижу ни одного метода, который бы принимал компарер (или еще что-нибудь) таким макаром.

S>Это тоже само что и перегрузка операторов. Все исходники для этого есть.

Перегрузка операторов — хорошо. Но это ad-hoc, а не параметрический полиморфизм.


S> Вот когда ваши шаблоны будут так разворачиваться тогда может ...

Не наши. Я болею за дотнет.
Re[53]: «Собаку съел»
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.01.17 10:47
Оценка:
Здравствуйте, samius, Вы писали:

S>>Еще раз Func<TSource, bool>


S>>TSource это дженерик параметр и никакой не инт

S>но это дженерик параметр метода Where. А метод, сравнивающий x и q — внезапно вовсе не дженериковый.
S>Вот как мне его показывает ILSpy:
S>Исходник
S>
S>       where (x >= lo) && (x <= hi)
S>

S>результат в ILSpy
S>
S>// ClassLibrary2.Class1.<>c__DisplayClass1_0
S>internal bool <Scale>b__0(int x)
S>{
S>    return x >= this.lo && x <= this.hi;
S>}
S>

S>Увы, дженерика не было.
S>В IL
S>[code]

Правильно потому что ты берешь уже выведенный дженерик класс
Ты должен смотреть System.Collections.Generic.List`1[T]

А ты сотришь уже созданный через MakeGenericType

System.Collections.Generic.List`1[int]
И сообветственно для него и компараторы должны быть с заменой T на int

Разницу чувствуешь?
и солнце б утром не вставало, когда бы не было меня
Re[54]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.01.17 12:25
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


S>Правильно потому что ты берешь уже выведенный дженерик класс

S>Ты должен смотреть System.Collections.Generic.List`1[T]

S>А ты сотришь уже созданный через MakeGenericType


S>System.Collections.Generic.List`1[int]

S> И сообветственно для него и компараторы должны быть с заменой T на int

S>Разницу чувствуешь?


Гхм. Насколько я помню, я смотрел результат работы компилятора C#, т.е. сборку с помощью ILSpy. А MakeGenericType — функция, которая не вызывается компилятором. Она вызывается рантаймом, следователььно результат ее работы вряд ли бы я мог обнаружить в сборке вместе с IL кодом. Логично?

Кроме того, обобщенная запись компаратора в C# — это Comparer<T>.Default.Compare(x, q), но никак не x < q.
То есть сейчас штатный компилятор C# без всяких переписываний сначала определяет тип Where<T> по первому аргументу и выводит Int32, потом подставляет в лямбде оператор сравнения двух интов. Для него лямбда, подсунутая в Where — это уже не дженерик метод.
Re[55]: «Собаку съел»
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.01.17 13:02
Оценка:
Здравствуйте, samius, Вы писали:

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


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


S>>Правильно потому что ты берешь уже выведенный дженерик класс

S>>Ты должен смотреть System.Collections.Generic.List`1[T]

S>>А ты сотришь уже созданный через MakeGenericType


S>>System.Collections.Generic.List`1[int]

S>> И сообветственно для него и компараторы должны быть с заменой T на int

S>>Разницу чувствуешь?


S>Гхм. Насколько я помню, я смотрел результат работы компилятора C#, т.е. сборку с помощью ILSpy. А MakeGenericType — функция, которая не вызывается компилятором. Она вызывается рантаймом, следователььно результат ее работы вряд ли бы я мог обнаружить в сборке вместе с IL кодом. Логично?


Она вызывается динамически. Но сам то по себе дженерик класс от этого никуда не делся. и его специализация для валуе типов будет для каждого своя, а вот для объектов будет одна.

S>Кроме того, обобщенная запись компаратора в C# — это Comparer<T>.Default.Compare(x, q), но никак не x < q.

S>То есть сейчас штатный компилятор C# без всяких переписываний сначала определяет тип Where<T> по первому аргументу и выводит Int32, потом подставляет в лямбде оператор сравнения двух интов. Для него лямбда, подсунутая в Where — это уже не дженерик метод.

Comparer это просто класс реализующий
public interface IComparable<in T>

и нетипизированный IComparer

Никто тебе не мешает создать свою реализацию на структуре.
В большинстве случаев это пережитки эпохи без дженериков

Сейчас ситуация така, что штатный компилятор делает то же само что и MakeGenericType в рантайме.
А вот Roslyn как раз и делает оптимизацию на уровне исходного кода, то же саме, что и в C++.
Там та же самая кодогенерация при специализации шаблона.
и солнце б утром не вставало, когда бы не было меня
Re[56]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.01.17 14:29
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


S>>Гхм. Насколько я помню, я смотрел результат работы компилятора C#, т.е. сборку с помощью ILSpy. А MakeGenericType — функция, которая не вызывается компилятором. Она вызывается рантаймом, следователььно результат ее работы вряд ли бы я мог обнаружить в сборке вместе с IL кодом. Логично?


S> Она вызывается динамически. Но сам то по себе дженерик класс от этого никуда не делся. и его специализация для валуе типов будет для каждого своя, а вот для объектов будет одна.

Так все-таки, каким образом я мог увидеть результат работы MakeGenericType в сборке?

S>>Кроме того, обобщенная запись компаратора в C# — это Comparer<T>.Default.Compare(x, q), но никак не x < q.

S>>То есть сейчас штатный компилятор C# без всяких переписываний сначала определяет тип Where<T> по первому аргументу и выводит Int32, потом подставляет в лямбде оператор сравнения двух интов. Для него лямбда, подсунутая в Where — это уже не дженерик метод.

S> Comparer это просто класс реализующий

S>
S>public interface IComparable<in T>

S>

То есть Int32 — это Comparer?
S> и нетипизированный IComparer
Оба сразу? А есть такие классы, которые реализуют сразу и то и другое?

S> Никто тебе не мешает создать свою реализацию на структуре.

S>В большинстве случаев это пережитки эпохи без дженериков
Конечно не мешает. Но что-то мешает мне свою реализацию на структуре подать по значению в LINQ методы типа Where.

S> Сейчас ситуация така, что штатный компилятор делает то же само что и MakeGenericType в рантайме.

Можно какую-либо демонстрацию вашего тезиса?
S> А вот Roslyn как раз и делает оптимизацию на уровне исходного кода, то же саме, что и в C++.
S>Там та же самая кодогенерация при специализации шаблона.
Кодогенерация при специализации шаблона? Можно подробнее? Или что вы здесь называете кодогенерацией? Подстановку типа что ли?
Re[57]: «Собаку съел»
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.01.17 15:08
Оценка:
Здравствуйте, samius, Вы писали:


S>> Сейчас ситуация така, что штатный компилятор делает то же само что и MakeGenericType в рантайме.

S>Можно какую-либо демонстрацию вашего тезиса?

Смотри http://infostart.ru/public/448668/

Смысл в том, что класс доступный через рефлексию с MakeGenericType и со статической компиляцией должны быть одинаковыми.
Эти ограничения сведены к минимуму в .Net Native
S>> А вот Roslyn как раз и делает оптимизацию на уровне исходного кода, то же саме, что и в C++.
S>>Там та же самая кодогенерация при специализации шаблона.
S>Кодогенерация при специализации шаблона? Можно подробнее? Или что вы здесь называете кодогенерацией? Подстановку типа что ли?

Я уже устал ссылку давать.
Optimising LINQ
roslyn-linq-rewrite

Там не просто подстановка типа но и оптимизация всех ветвей Linq запроса.
и солнце б утром не вставало, когда бы не было меня
Re: Visual C# vs C++. Надо сравнить перспективы.
От: Kaifa Россия  
Дата: 21.01.17 15:22
Оценка:
AO>Какие еще ключевые отличия C++ от C# ?

где вкуснее покормят, где девок покруче в баню подгонят — то и бери
именно так помню давным давно главбух выбрал и привез хрень на базе дб прогресс в одну дочку автоваза где я проторчал почти полгода )))
Re[58]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.01.17 15:28
Оценка:
Здравствуйте, Serginio1, Вы писали:

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



S>>> Сейчас ситуация така, что штатный компилятор делает то же само что и MakeGenericType в рантайме.

S>>Можно какую-либо демонстрацию вашего тезиса?

S> Смотри http://infostart.ru/public/448668/

Я не собираюсь в ближайшей перспективе осваивать 1C

S> Смысл в том, что класс доступный через рефлексию с MakeGenericType и со статической компиляцией должны быть одинаковыми.

Отсюда не вытекает то, что компилятор делает аналог MakeGenericType.

S>Эти ограничения сведены к минимуму в .Net Native

Какие ограничения?

S>>> А вот Roslyn как раз и делает оптимизацию на уровне исходного кода, то же саме, что и в C++.

S>>>Там та же самая кодогенерация при специализации шаблона.
S>>Кодогенерация при специализации шаблона? Можно подробнее? Или что вы здесь называете кодогенерацией? Подстановку типа что ли?

S> Я уже устал ссылку давать.

S>Optimising LINQ
S>roslyn-linq-rewrite

Когда я увидел слова "специализация" и "шаблон", то подумал что речь о C++, который в контексте упомнянут. А тут опять эта ссылка.

Я уже устал эту ссылку смотреть. От того что она тут очередной раз появляется, в ней не появляется инлайнинга параметрически полиморфных компараторов.

S>Там не просто подстановка типа но и оптимизация всех ветвей Linq запроса.

Я сдаюсь. Того, что я ожидал, я там не увижу, а время жаль.
Деревья выражений против шаблонов
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 22.01.17 06:18
Оценка:
Здравствуйте, samius, Вы писали:

На самом деле Linq это в том числе и деревья выражений Динамические Linq-запросы или приручаем деревья выражений

Динамическое построение Linq запроса

Которые могут компилироваться в рантайме. А могут и на этапе компиляции.
Для SQL это кодогенерация, а для Enumerable это компиляция обхода коллекции


Если использовать вместо
Вместо Func<t,bool>>

Expression<Func<t,bool>>

то все прекрасно будет инлайнится при специализации.

Класс Expression&lt;TDelegate&gt;
и солнце б утром не вставало, когда бы не было меня
Отредактировано 22.01.2017 6:31 Serginio1 . Предыдущая версия . Еще …
Отредактировано 22.01.2017 6:29 Serginio1 . Предыдущая версия .
Отредактировано 22.01.2017 6:26 Serginio1 . Предыдущая версия .
Re: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.01.17 06:41
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


S>На самом деле Linq это в том числе и деревья выражений Динамические Linq-запросы или приручаем деревья выражений


S>Динамическое построение Linq запроса


S> Которые могут компилироваться в рантайме. А могут и на этапе компиляции.

S> Для SQL это кодогенерация, а для Enumerable это компиляция обхода коллекции


S>Если использовать вместо

S>Вместо Func<t,bool>>

S>Expression<Func<t,bool>>


S> то все прекрасно будет инлайнится при специализации.


S>Класс Expression&lt;TDelegate&gt;

Не надо возить меня по этим азам. Писал я и свой LINQ провайдер для сериализации запросов когда-то. Все это совершенно не касается инлайнигна "параметрически полиморфных компараторов", если разобраться что такое "компаратор" и "параметрический полиморфизм".
Re[2]: «Собаку съел»
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 22.01.17 06:54
Оценка:
Здравствуйте, samius, Вы писали:

SS>Не надо возить меня по этим азам. Писал я и свой LINQ провайдер для сериализации запросов когда-то. Все это совершенно не касается инлайнигна "параметрически полиморфных компараторов", если разобраться что такое "компаратор" и "параметрический полиморфизм".


public static IEnumerable<T> Compose<T, Y>(this IEnumerable<T> src, Expression<Func<T, Y>> propertyExpression, Expression<Func<Y, bool>> func)
        {
            return src.Where(Expression.Lambda<Func<T, bool>>(Expression.Invoke(func, propertyExpression.Body), propertyExpression.Parameters).Compile());
        }



Чем тебе
Expression<Func<Y, bool>> func)

Не компаратор?
и солнце б утром не вставало, когда бы не было меня
Re[3]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.01.17 14:40
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

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


S> Чем тебе

S>
S>Expression<Func<Y, bool>> func)
S>

S>Не компаратор?

Тем, что оно не может принять два значения и сравнить их между собой, как это делают компараторы.
Re[4]: «Собаку съел»
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.01.17 07:18
Оценка:
Здравствуйте, samius, Вы писали:

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


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


S>> Чем тебе

S>>
S>>Expression<Func<Y, bool>> func)
S>>

S>>Не компаратор?

S>Тем, что оно не может принять два значения и сравнить их между собой, как это делают компараторы.

Ок

 Expression<Func<T,T,int>> func
и солнце б утром не вставало, когда бы не было меня
Re[5]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.01.17 08:16
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

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


S>>Тем, что оно не может принять два значения и сравнить их между собой, как это делают компараторы.

S>Ок

S>
S> Expression<Func<T,T,int>> func
S>

Отлично, благодарю.
Но это еще не компаратор, это только его сигнатура. Осталось написать параметрически полиморфное тело компаратора и продемонстрировать как оно инлайнится.
Re[6]: «Собаку съел»
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.01.17 08:31
Оценка: :))
Здравствуйте, samius, Вы писали:

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


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


S>>>Тем, что оно не может принять два значения и сравнить их между собой, как это делают компараторы.

S>>Ок

S>>
S>> Expression<Func<T,T,int>> func
S>>

S>Отлично, благодарю.
S>Но это еще не компаратор, это только его сигнатура. Осталось написать параметрически полиморфное тело компаратора и продемонстрировать как оно инлайнится.
То есть

System.Linq.Expressions.Expression<Func<int,int, int>> expr = (i,x) => i -x;


А как использовать деревья выражений я тебе уже кучу сслок давал.

На самом деле, что можно в рантайме, то можно и на этапе компиляции. Так или иначе компилятор строит AST дерево, и можно подставлять не адрес на функцию, а разворачитвать тело функции по адресу на этапе компиляции в CIL код.

public static IEnumerable<T> Compose<T, Y>(this IEnumerable<T> src, Expression<Func<T, Y>> propertyExpression, Expression<Func<Y, bool>> func)
        {
            return src.Where(Expression.Lambda<Func<T, bool>>(Expression.Invoke(func, propertyExpression.Body), propertyExpression.Parameters).Compile());
        }
и солнце б утром не вставало, когда бы не было меня
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.