Performance Unterschied: MethodInfo.Invoke <-> Linq.Expressions
-
Habs grad ausprobiert:
Linq.Expression: 193 ms
Method.Invoke: 4374 msDeiner ist schneller
-
Linq.Expression: 75 ms
Method.Invoke: 432 ms99,09% Main
- 67,95 % TestWithMethodInvoke
-- 57,97 % Invoke
--- 55,41 % Invoke
---- 25,58 % UnsafeInvokeInternal
----- 10,14 % TestMethod
---- 18,54 % InvokeArgumentCheck
---- 05,29 % PerformSecurityCheck
---- 01,00 % get_InvovationFlags- 29,78 % TestWithExpressions
-- 10,39 % TestMethod
-- 07,76 % CompileMethod
-
Ich benutze Invoke immer, um vom Workerthread auf den UI-Thread zu kommen. Ist der Threadwechsel das teure?
-
volkard schrieb:
Ich benutze Invoke immer, um vom Workerthread auf den UI-Thread zu kommen. Ist der Threadwechsel das teure?
*Lach* - vielleicht solltest du die Frage nochmal reflektieren
Es geht um Zeile 72 und Zeile 82 von Dravere Code - Reflection in .NET
-
Ich komme auf folgende Werte:
Linq.Expression: 66 ms Method.Invoke: 1021 ms
P.S. Eure Kisten sind ja lahm :p
P.S. 2: Man kann die Laufzeiten mit Reflection auf ca. 1/2 der LINQ-Expression Lösung drücken, wenn man von Method.Invoke weggeht und ein Delegate erstellt, welches mit der MethodInfo werkelt
-
GPC schrieb:
P.S. Eure Kisten sind ja lahm :p
Wird sind halt arme Leute und schwimmen nicht im Geld
GPC schrieb:
P.S. 2: Man kann die Laufzeiten mit Reflection auf ca. 1/2 der LINQ-Expression Lösung drücken, wenn man von Method.Invoke weggeht und ein Delegate erstellt, welches mit der MethodInfo werkelt
Kannst du das ein wenig näher erläutern? Mit dem
Linq.Expression
wird ja bereits ein Delegate erzeugt.Grüssli
-
Dravere schrieb:
GPC schrieb:
P.S. 2: Man kann die Laufzeiten mit Reflection auf ca. 1/2 der LINQ-Expression Lösung drücken, wenn man von Method.Invoke weggeht und ein Delegate erstellt, welches mit der MethodInfo werkelt
Kannst du das ein wenig näher erläutern? Mit dem
Linq.Expression
wird ja bereits ein Delegate erzeugt.Na logisch
Im Prinzip ist es ganz einfach: Anstatt Method.Invoke zu benutzen, erzeugt man einfach mit der MethodInfo ein Delegate und führt darüber dann den Code aus:
private static long TestWithMethodInvoke(int times) { var obj = new Program(); var method = obj.GetType().GetMethod("TestMethod"); object first = 0m; object second = 1m; //Awesomeness happens here Func<decimal, decimal, decimal> m = (Func<decimal, decimal, decimal>)Delegate.CreateDelegate(typeof(Func<decimal, decimal, decimal>), obj, method); var stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < times; ++i) { first = m((decimal)first, (decimal)second); } stopwatch.Stop(); return stopwatch.ElapsedMilliseconds; }
Das gibt dann im Debug-Mode ca. solche Zeiten:
Linq.Expression: 65 ms Method.Invoke: 30 ms
-
Warning sematische Optimierung gefunden!
Linq.Expression: 57 ms
Method.Invoke: 36 msgrml nur 2ms schneller als gpc mit schlechteren Rechner
-
@GPC,
Dann kannst du ja auch gleich einDelegate
durchreichen.In meinem Beispiel bin ich sehr generisch und arbeite mit
object
. Ich verwandle jedeMethodInfo
in einFunc<object[], object>
. Das Array, welches übergeben wird, enthält an der Indexposition 0 das Objekt der Methode und im Rest des Arrays befinden sich die Parameter. Damit kannst du eine Methode aufrufen, nur in dem du den Namen von dieser Kennst, das Objekt dazu bekommst und die Parameter als Liste vonobject
. Kann man z.B. sehr gut in einer Skriptsprache verwenden, wo deine Methode nicht funktionieren würdeGrüssli
-
Da hast du natürlich Recht, man büßt ein gutes Stück Verallgemeinerung ein ;/ Ich hatte das damals gebraucht, um einen festen Satz an Methoden per Reflection auf verschiedene COM-Komponenten aufzurufen. Insofern war die Methodensignatur bei mir statisch
Mich interessiert aber auch, wieso Methode.Invoke sooo viel langsamer ist.. mal nach der Mittagspause forschen