동적 코드 생성으로 성능을 향상시킬 수있는 방법이 있지만이 문제를 해결하는 가장 좋은 방법은 무엇인지 모르겠습니다.성능을위한 동적 컴파일
내가
class Calculator
{
int Value1;
int Value2;
//..........
int ValueN;
void DoCalc()
{
if (Value1 > 0)
{
DoValue1RelatedStuff();
}
if (Value2 > 0)
{
DoValue2RelatedStuff();
}
//....
//....
//....
if (ValueN > 0)
{
DoValueNRelatedStuff();
}
}
}
DoCalc 방법은 낮은 수준에있는 클래스가 그것을 계산하는 동안 여러 번이라고 가정하자. 또 다른 중요한 측면은 ValueN이 처음에만 설정되고 계산 중에는 변경되지 않는다는 것입니다. 그래서 DoCalc 메서드의 if 함수 중 많은 것이 ValueN 중 많은 수가 0이므로 불필요합니다. 따라서 동적 코드 생성이 성능을 향상시키는 데 도움이 될 수 있기를 바랍니다. 예를 들어
내가 방법을
void DoCalc_Specific()
{
const Value1 = 0;
const Value2 = 0;
const ValueN = 1;
if (Value1 > 0)
{
DoValue1RelatedStuff();
}
if (Value2 > 0)
{
DoValue2RelatedStuff();
}
....
....
....
if (ValueN > 0)
{
DoValueNRelatedStuff();
}
}
을 만들고 최적화를 컴파일하는 경우는 C# 컴파일러에 전환 만 필요한 물건을 유지하는만큼 영리하다. 그래서 ValueN의 값을 기반으로 런타임에 이러한 메서드를 만들고 계산 중에 생성 된 메서드를 사용하려고합니다.
표현식 트리를 사용할 수는 있지만 표현식 트리는 간단한 람다 함수에서만 작동하므로 함수 본문 내부에서 if, while 등을 사용할 수 없습니다. 따라서이 경우 적절한 방법으로이 메서드를 변경해야합니다.
또 다른 가능성은 문자열로 필요한 코드를 만들고이를 동적으로 컴파일하는 것입니다. 그러나 기존의 방법을 취하여 그에 맞게 수정할 수 있다면 훨씬 더 나을 것입니다.
리플렉션이 있습니다. 전송하지 마세요. 유지하기가 매우 어려워서 붙잡고 싶지 않습니다.
BTW. 나는 C#에 국한되지 않는다. 그래서 이런 종류의 문제에 가장 적합한 프로그래밍 언어에 대한 제안에 대해 열려 있습니다. 두 가지 이유로 LISP를 제외하고.
하나의 중요한 설명. DoValue1RelatedStuff() 내 알고리즘에서 메서드 호출이 아닙니다. 공식 기반의 계산 일 뿐이지 만 꽤 빠릅니다. 나는 몇 가지 성능 테스트를 실행 한이
if (Value1 > 0)
{
// Do Value1 Related Stuff
}
처럼 작성해야 내가 두 IFS 하나는 최적화 방법은 경우 중복보다 약 2 배 빠른 사용할 수 없을 때 볼 수 있습니다.
여기에 내가 테스트에 사용 된 코드는 다음과 같습니다
public class Program
{
static void Main(string[] args)
{
int x = 0, y = 2;
var if_st = DateTime.Now.Ticks;
for (var i = 0; i < 10000000; i++)
{
WithIf(x, y);
}
var if_et = DateTime.Now.Ticks - if_st;
Console.WriteLine(if_et.ToString());
var noif_st = DateTime.Now.Ticks;
for (var i = 0; i < 10000000; i++)
{
Without(x, y);
}
var noif_et = DateTime.Now.Ticks - noif_st;
Console.WriteLine(noif_et.ToString());
Console.ReadLine();
}
static double WithIf(int x, int y)
{
var result = 0.0;
for (var i = 0; i < 100; i++)
{
if (x > 0)
{
result += x * 0.01;
}
if (y > 0)
{
result += y * 0.01;
}
}
return result;
}
static double Without(int x, int y)
{
var result = 0.0;
for (var i = 0; i < 100; i++)
{
result += y * 0.01;
}
return result;
}
}
'System.Linq.Expressions'를 사용하고자한다면 항상 조건부로 표현 트리를 만들 수 있습니다. 처음에 썼던 것과 완전히 똑같지는 않겠지 만, 거의 확실하게 작동 할 것이고 System.Reflection.Emit보다 유지 보수가 가능할 것이고, 또한 더 나은 성능을 발휘할 수있는 좋은 기회가 있습니다. –
표현 트리가있는 솔루션이 가장 유망한 것으로 보입니다. 그러나 일반적으로 어떤 방법 으로든이 방법으로 최적화 할 수있는 도구를 갖고 싶습니다. – Max