Pull to refresh
87
0

Open source contributor

Так в том и дело, что собрав код в Linq.Expression, его можно собрать в делегат одним методом. А вот этот делегат будет лишь наносекунды медленнее чем если написать тот же код вручную

Да генерит вроде... не мерил, если честно. Точнее мерил, вот здесь, но не сравнивал с LINQ.

Неа. Там отдельный type argument на них, и для них тип специализируется

Во всех методах ожидается структа-делегат реализующая IValueDelegate.


По идее, чтобы выжать максимально скорости работы, нужно написать структуру, реализовав интерфейс и в методе Invoke написать ваш делегат.


Но так как это не слишком интересно никому, я предварительно сделал PureValueDelegate и CapturingValueDelegate, которые работают без аллокаций, но используют обычный дотнетовский делегат.

Хорошо. Сделал бенчмарк для сравнения простого Select + Where для RefLinq против классического.

Собственно, примерное отношение 1:2 по времени так и сохраняется, как и предполагалось ;).

Исходники бенчмарка тут.

cc @Mingun , @andreyverbin

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

Еще могли бы рассказать как получили бэкграунд в низкоуровневой разработке? Помогло ли образование (наше или зарубежное?) или же достигали самостоятельно? Возможно порекомендуете какие-либо книги?

Самостоятельно, но не без помощи других людей и проектов. В основном это

  1. C# сервер в дискорде - тут куча крутых людей, очень много чего низкоуровнего можно узнать

  2. Шарплаб

  3. Ну и несколько книжек:

    1. CLR via C# 4-th edition

    2. Pro .NET Memory Management

    3. Pro .NET Benchmarking

    4. https://en.wikibooks.org/wiki/X86_Assembly

Вот реально редко встретишь людей из наших, которые так глубоко копают.

А ведь на том сишарп сервере есть люди, которые в этом шарят на порядки больше меня! Вот это реально клад

Расскажите как у вас хватает времени на это все, откуда берете мотивацию, энергию?

Позитивный фидбек пользователей и читателей дает мотивацию.


Является ли это вашей личной инициативой или кто-то курирует?

Личная. Никто не финансирует.( Но надо сказать, что многие проекты не так-то и много заняли времени. Например, проект, про который эта статья, я сделал наверное дня за два. AsmToDelegate — там моей работы вовсе немного, по сути все, что я делаю, это пишу закодированный машинный код от Iced-а в исполняемую память и возвращаю делегат.


Хотя есть конечно и большие проекты, которые уже не первый год делаю, например этот

Это хороший вопрос, но я не изучал. Вообще, code bloating — это причина почему, например, CLR не генерирует типы и методы на каждый тип, а только на разные value type. То есть такая проблема явно есть. Но какое именно потребление — наверное можно попробовать померить через EventListener, отследив момент когда JIT специализирует тип

Вовсе нет. Стандартный LINQ работает вполне "обычно", без Linq.Expression. Вот здесь можно посмотреть исходники LINQ-а.


Но для работы со всякими базами данных используется IQueryable, и вот там используются Linq.Expression, чтобы переделать лямбду на сишарпе в SQL-запрос (или как это в БД работает). Но это уже совсем другая история.

А еще знакомый пилит компилятор LINQ в обычные циклы/условия и т. д., вот там он использует компиляцию Linq.Expression.

Неужели компилятор настолько глупый, что не может заинлайнить все эти виртуальные вызовы? Он же видит всю Linq-цепочку (в вашем примере).

Пока да. Чтобы девиртуализировать такую длинную цепочку, ему придется буквально выполнить весь код и убедиться, что у нас всегда создаются одни и те же типы, и заинлайнить огромное количество кода. Для подобных вещей это бессмысленно и стоит очень много времени джита (а он, конечно, должен работать очень быстро).

Все заинлайненные лямбды должен же иметь нулевой размер, они не используют состояние

В моем примере я использую тип PureValueDelegate. Это такой value delegate, только для ленивых, потому что в нем я использую обычный Func :). В идеале туда можно передавать настоящий функтор вручную реализуя IValueDelegate, но кажется это никому из пользователей LINQ-а неинтересно такой ужас городить. Вот. То есть это как минимум 8 байт на каждый такой делегат.

а размер конечной структуры по идее должен быть максимальным размером всех этих переходных структур?

Ну, размер каждой следующей - сумма ее полей, то есть "личных" полей и предыдущего енумератора.

Плюс еще инлайнер джита мог уже выйти из бюджета и перестать инлайнить некоторые методы - тогда у нас еще и копирование будет.

А я все-таки не понимаю, зачем право одобрять/не одобрять комменты дали авторам. Мне кажется, это не их задача

Дальше теория - львиная доля из 4 и 8 мс это выделение памяти

На самом деле нет, память, как вы же сами сказали, стоит очень мало. Правда все-таки побольше, чем на стеке, но все равно немного.

А вот виртуальные вызовы на каждом шагу - вот это я думаю и занимает все время. Если сделать цепочку из N операций в LINQ, то каждый Move.Next это будет N виртуальных вызовов, то есть хождений по случайным местам памяти.

А тут нет виртуальных вызовов, и многие вызовы заинлайнены.

Это перевод моей же статьи на медиуме.

Вопросы, фидбек приветствуются!

Не в проце там дело, как оказалось, а в операционке

Честно говоря, превью статьи, встречающая меня с мутирующей лямбдой в linq, довольно оттвергает от чтения. Надеюсь, кому-то все-таки будет полезно...

Сработает, конечно. 1 час / 12 минут будет 0.08 час/мин :).

На самом деле еще нужен метод упрощения, который упрощал бы, например, деление единиц с одной базы до просто скалярного значения. Пока что при любой операции само выражение единицы измерения будет только нарастать.

Я же говорю - нет. В твоем коде + все равно НЕ дженерик оператор. Интерфейс никак ни на что не влияет. Интерфейс нужен для того, чтобы уметь ограничить тип до того, у которого есть оператор. А мне нужен дженерик оператор. А его нет. Совсем нет.

Это приватная реализация, или как она там называется, а не дженерик оператор.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity