- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace DynUnloop
{ // Суммирование в цикле
class SumLooping
{ public int Summ(int valMax)
{ int result = 0;
for (int i = 0; i <= valMax; i++)
result += i;
return result;
}
}
// Плоское суммирование
class SumFlat
{ interface ISumCode
{ int ComputeSumm(int valMax);
}
void WriteCode(int valMax)
{ AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "SumFlatAssembly";
AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(
assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =
assemblyBuilder.DefineDynamicModule("SumFlatModule");
TypeBuilder typeBuilder =
moduleBuilder.DefineType("SumFlatClass"
, TypeAttributes.Public);
typeBuilder.AddInterfaceImplementation(typeof(ISumCode));
/// Задаём возвращаемое зачение и параметр
Type[] paramTypes = { typeof(int) };
Type returnType = typeof(int);
MethodBuilder methodBuilder =
typeBuilder.DefineMethod("ComputeSumm"
, MethodAttributes.Public
| MethodAttributes.Virtual
, returnType, paramTypes);
ILGenerator il = methodBuilder.GetILGenerator();
// Генерируем плоский код.
il.Emit(OpCodes.Ldc_I4, 0);
for (int i = 1; i <= valMax; i++)
{ il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Add);
}
il.Emit(OpCodes.Ret);
// Перекрываем метод ComputeSumm и создаём тип SumFlatClass.
MethodInfo methodInfo =
typeof(ISumCode).GetMethod("ComputeSumm");
typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
typeBuilder.CreateType();
/// Код готов, создаём объект и берем его интерфейс.
code = (ISumCode)assemblyBuilder.CreateInstance("SumFlatClass");
}
public int Summ(int val)
{ if (this.code == null)
WriteCode(val);
return this.code.ComputeSumm(val);
}
ISumCode code;
}
Оригинальный стиль кода и комментарии сохранёны. (с), или как там.
В коде - разворачивание цикла в "плоский" IL код, который, как доказывается должен выигрывать по производительности.
А возможность очень полезная, и тогда замыкания (жалкое, тормозное подобие этой фичи) станут не нужны.
К сожалению, я пока лишь присматриваюсь к Немерле, метапрограммирование в нём ещё толком не освоил. Однако из немерловых макросов действительно доступны всю фишки компилятора. Макросы могут, например, и в базу данных слазить, и куда-нибудь в тырнет обратиться. И это всё в компайл-тайме!
error c404: Fatal compilation error. Page not found.
Просто дело в том, что сейчас в процессе билда сложных приложений скрипты и в базы данных лезут, и прочее. Но пишутся эти билд-скрипты на чём-то левом, не на родном языке приложения, будь то C++,C#,Java. Используются препроцессоры, make-файлы, батники, питоны, баши и прочее. Естественно, это не упрощает процесс разработки. И это требует наличие в системе интерпретаторов этих скриптовых языков. То есть скачаешь опенсорсную софтину на Си, а для её компиляции ещё и кучу скриптовых языков придётся поставить.
В отличие от них, для компиляции немерловых программ достаточно единственного компилятора, который выполнит всё то же самое.
http://msdn.microsoft.com/ru-ru/library/system.linq.expressions.expression.aspx - зацени список методов, с помощью которых можно конструировать выражения.
http://msdn.microsoft.com/en-us/library/bb397951.aspx - небольшие примеры кода.
То что нужно?
Да, выглядит громоздко. Но тут ещё дело в том, что в Лиспе - динамическая типизация. А в C# строгая статическая, поэтому кодогенерация как ни крути будет сложнее.
Наверняка обзовут блаб-программистом, но ответят :).
P.S. хм, Страйко, что значит:
Ошибка компиляции комментария:
1. csrf verification error
?
Только осторожно, пристегнитесь. А то свалитесь под стол.
Парень жжет: Пусть это будет просто, просто как только можно, но не проще...
Ему бы в рекламу абибаса
Лучше бы он эту фразу помнил, ибо объяснить он так ничего и не смог(причем никакими словами вообще). Не качественный какой-то тролль попался
Профи пользуют Voodoo. Пока не ретро у тебя видяха. Нечего хвастаться. Я прямо таки как в музей сходил.
> КУ!
Вот и молодец.
Не то оптимизируете, товарищи, ох не то.
Однако, я скомпилировал этот пример с помощью Виртуалпаскаля и Дельфи. И там, и там паскалевский код выполнялся вдвое быстрее ассемблерного. Сенсация! Теория опровергнута!
Дизассемблировал поделки этих компиляторов... После этого переписал пример на Ассемблере — в VP и Дельфи время выполнения оказалось примерно одинаковым. Опубликовать результаты говнокодом или на высер компилятора смотреть будет скучно?
Из этого должна следовать какая-то мораль. Только пока не могу понять, какая.
А результаты давай, публикуй. Может интересно будет обсудить.
И ещё раз хочу упомянуть JIT: в виртуальных машинах он может любой код переделать на своё усмотрение. Поэтому вылизывать код вручную становится вообще бессмысленно. Ты задашь такой набор команд, а JIT выкинет их нах, и вставит свой.