できるだけ早く多くの手動指定の計算を実行し、DLRの使用を検討しているWebサービスを作成しようとしています。DLR&パフォーマンス
申し訳ありませんが、これは長いですが、スキムオーバーして、一般的な要点を自由に感じる。
IronPythonライブラリは、計算を非常に簡単にするために使用しています。私の作品のラップトップは、第二次やっあたり40万の計算のパフォーマンスを提供します:DynamicValueは、事前に構築された配列(播種し、実行時に構築された)から乱数を返すクラスがある
ScriptEngine py = Python.CreateEngine();
ScriptScope pys = py.CreateScope();
ScriptSource src = py.CreateScriptSourceFromString(@"
def result():
res = [None]*1000000
for i in range(0, 1000000):
res[i] = b.GetValue() + 1
return res
result()
");
CompiledCode compiled = src.Compile();
pys.SetVariable("b", new DynamicValue());
long start = DateTime.Now.Ticks;
var res = compiled.Execute(pys);
long end = DateTime.Now.Ticks;
Console.WriteLine("...Finished. Sample data:");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(res[i]);
}
Console.WriteLine("Took " + (end - start)/10000 + "ms to run 1000000 times.");
。
同じことをするためのDLRクラスを作成すると、はるかに高いパフォーマンス(1秒間に10,000,000回の計算)が得られます。
class DynamicCalc : IDynamicMetaObjectProvider
{
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
{
return new DynamicCalcMetaObject(parameter, this);
}
private class DynamicCalcMetaObject : DynamicMetaObject
{
internal DynamicCalcMetaObject(Expression parameter, DynamicCalc value) : base(parameter, BindingRestrictions.Empty, value) { }
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
Expression Add = Expression.Convert(Expression.Add(args[0].Expression, args[1].Expression), typeof(System.Object));
DynamicMetaObject methodInfo = new DynamicMetaObject(Expression.Block(Add), BindingRestrictions.GetTypeRestriction(Expression, LimitType));
return methodInfo;
}
}
}
と以下のようにして、同じ方法で試験/と呼ばれている:クラスは次のとおりですAR1とAR2は、事前に構築されている
dynamic obj = new DynamicCalc();
long t1 = DateTime.Now.Ticks;
for (int i = 0; i < 10000000; i++)
{
results[i] = obj.Add(ar1[i], ar2[i]);
}
long t2 = DateTime.Now.Ticks;
、乱数のランタイム播種配列を。
速度はこのように素晴らしいですが、計算を指定するのは簡単ではありません。私は基本的に自分自身のレクサー&パーサーを作成していますが、IronPythonにはすでに必要なものがすべてあります。
IronPythonはDLRの上に実装されているため、パフォーマンスが向上すると思っていました。
私はIronPythonエンジンを最大限に活用していますか?それよりもはるかに優れたパフォーマンスを得ることは可能ですか?
実施例1とが、C#でのループと同じ(編集)、変数を設定し、Python関数を呼び出す:PYSをPYからScriptScopeであり、そしてargs1が事前に構築されたアレイである
ScriptSource src = py.CreateScriptSourceFromString(@"b + 1");
CompiledCode compiled = src.Compile();
double[] res = new double[1000000];
for(int i=0; i<1000000; i++)
{
pys.SetVariable("b", args1[i]);
res[i] = compiled.Execute(pys);
}
ランダムな二倍。この例では、Pythonコードでループを実行し、配列全体を渡すよりも遅く実行します。
私はIronPythonについて、あるいは私の提案のパフォーマンスへの影響についてよく分かりませんが、Pythonをよく知っている人はほとんど誰でも、このような関数を書くでしょう: 'return [b.GetValue()+ 1 for _ in xrange(1000000)] ' – delnan
私はPythonをよく知らないので、チップのおかげで! –