Почему не сохраняющиеся в кэше не захватывающие деревья выражений, инициализированные с помощью лямбда-выражений?
Я написал этот код в компиляторе, как в исходной реализации C # 3, так и вRoslyn rewrite.
Как я всегда говорю, когда задают вопрос "почему нет": авторам компилятора не требуется , чтобы указать причину, по которой они не сделай что-нибудь .Выполнение чего-либо требует работы, требует усилий и стоит денег.Поэтому позиция по умолчанию всегда состоит в том, чтобы не что-то делать, когда работа не нужна.
Скорее, человек, который хочет проделанную работу, должен обосновать, почему эта работа стоит затрат.И на самом деле, требование сильнее, чем это.Человек, который хочет, чтобы работа была проделана, должен объяснить, почему ненужная работа является лучшим способом потратить время, усилия и деньги, чем любое другое возможное использование времени разработчика .Существует буквально бесконечное количество способов улучшить производительность компилятора, набор функций, надежность, удобство использования и так далее.Что делает его таким замечательным?
Теперь, когда я даю это объяснение, я получаю отговорку, говоря: «Microsoft богата, бла-бла-бла».Наличие большого количества ресурсов - это не то же самое, что наличие бесконечных ресурсов, а компилятор уже очень дорогой.Я также получаю отговорку, говоря, что «открытый исходный код освобождает рабочую силу», что абсолютно не делает.
Я заметил, что время было фактором.Это может быть полезно, чтобы расширить это дальше.
Когда C # 3.0 разрабатывался, в Visual Studio была определенная дата, когда он должен был быть "выпущен в производство", странный термин с того времени, когда программное обеспечение распространялось в основном на компакт-дисках, которые нельзя было изменить после того, как онибыли напечатаны.Эта дата не была произвольной;скорее следовала целая цепочка зависимостей.Если бы, скажем, SQL Server имел функцию, которая зависела от LINQ, не было бы никакого смысла откладывать выпуск VS до тех пор, пока не выйдет SQL Server того же года, и поэтому расписание VS повлияло на расписание SQL Server, что, в свою очередь, повлияло на другие команды.расписания и т. д.
Таким образом, каждая команда в организации VS представила расписание, и команда с наибольшим количеством дней работы над этим графиком была «длинным полюсом».Команда C # была длинным полюсом для VS, а я был длинным полюсом для команды компиляторов C #, поэтому каждый день, когда я опаздывал с предоставлением функций компилятора, был днем, когда Visual Studio и каждый последующий продуктускользнуть от графика и разочаровать своих клиентов .
Это мощное препятствие для выполнения ненужной работы с производительностью, в частности работы с производительностью, которая может ухудшить, а не улучшить .Кэш без политики истечения имеет имя: это утечка памяти .
Как вы заметили, анонимные функции кэшируются.Когда я реализовал лямбда-выражения, я использовал тот же код инфраструктуры, что и для анонимных функций, так что кеш был (1) «потопленной» - работа была уже выполнена, и было бы больше работы, чтобы отключить ее, чем оставить ее включенной, и(2) уже были проверены и проверены моими предшественниками.
Я подумал о реализации аналогичного кэша на деревьях выражений, используя ту же логику, но понял, что это будет (1) работа, которая требует времени, которого у меня уже было мало, и (2) у меня не былоПредставление о влиянии производительности на кэширование такого объекта. Делегаты действительно маленькие .Делегаты являются одним объектом;если делегат логически статичен, что агрессивно кэширует C #, он даже не содержит ссылку на получателя.Деревья выражений, напротив, потенциально огромные деревья .Это граф маленьких объектов, но этот граф потенциально большой.Графики объектов делают работу сборщика мусора тем дольше, чем они живут!
Следовательно, какие бы тесты производительности и показатели не использовались для обоснования решения о кэшировании делегатов, они не будут применимы к деревьям выражений, поскольку нагрузка на память совершенно другая.Я не хотел создавать новый источник утечек памяти в нашей самой важной новой языковой функции.Риск был слишком высок.
Но риск может стоить того, если выгода велика.Так в чем же выгода?Начните с вопроса: «Где используются деревья выражений?»В LINQ запросы, которые будут удалены в базы данных. Это очень дорогая операция как по времени, так и по памяти .Добавление кеша не даст вам большого выигрыша, потому что работа, которую вы собираетесь сделать, в миллионы раз дороже, чем выигрыш;победа это шум.
Сравните это с победой делегатов.Разница между «выделить x => x + 1
, затем назвать его« миллион раз »и« проверить кэш, если он не кэшируется, выделить его, вызвать его »заключается в обмене выделения на проверку, которая может сэкономить вам целые наносекунды.Это кажется несущественным, но вызов также займет наносекунды , поэтому в процентном отношении это важно.Кэширование делегатов - явная победа.Кэширование деревьев выражений не близко к чистой победе;нам нужны данные, что это преимущество, которое оправдывает риск.
Поэтому было легко принять решение не тратить время на эту ненужную, вероятно, незаметную, неважную оптимизацию в C # 3.
Во время C # 4 у нас было много более важных дел, чем пересмотреть это решение.
После C # 4 команда разделилась на две подгруппы, одну для переписывания компилятора Roslyn, идругой для реализации async-await в исходной базе кода компилятора.Команда async-await была полностью поглощена реализацией этой сложной и сложной функции, и, конечно, команда была меньше, чем обычно.И они знали, что вся их работа в конечном итоге будет воспроизведена в Рослине, а затем выброшена;этот компилятор был в конце своей жизни.Таким образом, не было никакого стимула тратить время или усилия на добавление оптимизаций.
Предлагаемая оптимизация была в моем списке вещей, которые нужно учитывать, когда я переписывал код в Roslyn, но нашим главным приоритетом было обеспечение работы компилятора до конца.до того, как мы оптимизировали небольшие его части, и я покинул Microsoft в 2012 году, до того, как эта работа была закончена.
Что касается того, почему никто из моих коллег не вернулся к этой проблеме после того, как я ушел, вам придется спроситьих, но я уверен, что они были очень заняты, выполняя реальную работу над реальными функциями, которые были запрошены реальными клиентами, или над оптимизацией производительности, которая имела большие выигрыши при меньшей стоимости.В эту работу входил компилятор с открытым исходным кодом, который недешев.
Итак, если вы хотите, чтобы эта работа была выполнена, у вас есть несколько вариантов.
- Компилятор с открытым исходным кодом;Вы могли бы сделать это самостоятельно.Если это звучит как большая работа, приносящая очень мало пользы для вас, то теперь у вас есть более понятное понимание того, почему никто не выполнял эту работу с тех пор, как эта функция была внедрена в 2005 году.
КонечноЭто все еще не "бесплатно" для команды компилятора.Кому-то придется тратить время, силы и деньги на анализ вашей работы.Помните, что большая часть затрат на оптимизацию производительности - это не те пять минут, которые требуются для изменения кода.Это недели тестирования на примере всех возможных реальных условий, которые демонстрируют, что оптимизация работает и не делает вещи хуже!Производительность - самая дорогая работа, которую я делаю.
- Процесс проектирования открыт.Введите проблему и в этом выпуске укажите убедительную причину, по которой вы считаете, что это улучшение того стоит.С данными.
Пока все, что вы сказали, это почему возможно .По возможности не режет!Многое возможно.Приведите цифры, которые объясняют, почему разработчики компиляторов должны тратить свое время на создание этого усовершенствования, а не на реализацию новых функций, запрашиваемых клиентами.
Фактический выигрыш в избежании повторного выделения сложных деревьев выражений позволяет избежать сбор давления , и это серьезная проблема.Многие функции в C # разработаны, чтобы избежать давления при сборе, и деревья выражений НЕ являются одним из них. Мой совет, если вы хотите, чтобы эта оптимизация была сосредоточена на ее влиянии на давление, потому что именно здесь вы найдете самый большой выигрыш и сможете дать самый убедительный аргумент.