Деревья выражений против IL.Emit для специализации кода во время выполнения - PullRequest
1 голос
/ 15 января 2012

Недавно я узнал, что можно генерировать код C # во время выполнения, и я хотел бы использовать эту функцию.У меня есть код, который выполняет некоторые очень простые геометрические вычисления, такие как вычисление пересечений линий и плоскостей, и я думаю, что мог бы получить некоторые преимущества в производительности, генерируя специализированный код для некоторых методов, потому что многие вычисления выполняются для одной и той же плоскости или той же линии нади снова.Специализируя код, который вычисляет пересечения, я думаю, что смогу получить некоторые преимущества в производительности.

Проблема в том, что я не уверен, с чего начать.Прочитав несколько постов в блоге и просмотрев документацию MSDN, я обнаружил две возможные стратегии генерации кода во время выполнения: деревья выражений и IL.Emit.Использование деревьев выражений кажется намного проще, потому что нет необходимости изучать что-либо об OpCodes и различных других тонкостях, связанных с MSIL, но я не уверен, что деревья выражений работают так же быстро, как MSIL, созданный вручную.Так есть ли какие-либо предложения о том, какой метод мне следует использовать?

Ответы [ 2 ]

4 голосов
/ 15 января 2012

Производительность обоих обычно одинакова, поскольку деревья выражений внутренне просматриваются и генерируются как IL с использованием тех же базовых системных функций, которые вы использовали бы сами. Теоретически возможно испускать более эффективный IL, используя низкоуровневые функции, но я сомневаюсь, что будет какой-либо практически важный прирост производительности. Это будет зависеть от задачи, но я не пришел ни к какой практической оптимизации испускаемого IL по сравнению с тем, который испускается деревьями выражений.

Я настоятельно рекомендую приобрести инструмент под названием ILSpy для обратной компиляции сборок CLR. При этом вы можете посмотреть на код, фактически пересекающий деревья выражений и фактически испускающий IL.

Наконец, предостережение. Я использовал деревья выражений в синтаксическом анализаторе языка, где вызовы функций связаны с правилами грамматики, которые компилируются из файла во время выполнения. Скомпилировано является ключом здесь. Для многих проблем, с которыми я сталкивался, когда то, чего вы хотите достичь, известно во время компиляции, вы не получите большую производительность при генерации кода во время выполнения. Некоторые оптимизации CLR JIT также могут быть недоступны для динамического кода. Это всего лишь мнение из моей практики, и ваш домен будет другим, но если производительность критична, я бы лучше посмотрел на нативный код, высоко оптимизированные библиотеки. Некоторая часть работы, которую я проделал, была бы медленной, если не использовать LAPACK / MKL. Но это только тот совет, который не просили, поэтому возьмите его с крошкой соли.

2 голосов
/ 15 января 2012

Если бы я был в вашей ситуации, я бы попробовал альтернативы от высокого уровня до низкого уровня, увеличивая «необходимое время и усилие» и уменьшая порядок повторного использования, и я бы остановился, как только производительность пока достаточно хороша. , т.е.:

  • во-первых, я бы проверил, есть ли у Math.NET, LAPACK или какой-либо подобной числовой библиотеки уже подобная функциональность, или я могу адаптировать / расширить код для своих нужд;

  • секунду, я бы попробовал деревья выражений;

  • в-третьих, я бы проверил Roslyn Project (хотя он и в предварительной версии);

  • в-четвертых, я бы подумал о написании общих процедур с небезопасным кодом C;

  • [пятое, я бы подумал о том, чтобы бросить и начать новую карьеру в другой профессии :)],

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

Но, возможно, я склонен против подходов низкого уровня; Ваш опыт, опыт и точка зрения могут отличаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...