c# - specific - system type:: gettype




Leistung von Object.GetType() (4)

Die GetType() Funktion ist mit dem speziellen Attribut [MethodImpl(MethodImplOptions.InternalCall)] markiert. Das bedeutet, dass der Methodentext keine IL enthält, sondern ein Hook in die Interna der .NET CLR ist. In diesem Fall untersucht es die binäre Struktur der Metadaten des Objekts und konstruiert ein System.Type Objekt um das Objekt herum.

EDIT: Ich glaube ich lag falsch bei etwas ...

Ich sagte das: "weil GetType() erfordert, dass ein neues Objekt erstellt wird", aber es scheint, dass dies nicht korrekt ist. Irgendwie speichert die CLR den Type und gibt immer das gleiche Objekt zurück, so dass kein neues Typ-Objekt erstellt werden muss.

Ich stütze mich auf folgenden Test:

Object o1 = new Object();
Type t1 = o1.GetType();
Type t2 = o1.GetType();
if (object.ReferenceEquals(t1,t2))
    Console.WriteLine("same reference");

Also erwarte ich nicht viel Gewinn in Ihrer Implementierung.

Wir haben viele Logging-Anrufe in unserer App. Unser Logger verwendet einen System.Type-Parameter, um anzuzeigen, welche Komponente den Aufruf erstellt hat. Manchmal, wenn wir belästigt werden können, machen wir etwas wie:

class Foo
{
  private static readonly Type myType = typeof(Foo);

  void SomeMethod()
  {
     Logger.Log(myType, "SomeMethod started...");
  }
 }

Dazu muss das Type-Objekt nur einmal abgerufen werden. Wir haben jedoch keine tatsächlichen Messwerte dazu. Jeder hat eine Idee, wie viel dies spart beim Aufruf dieses.GetType () jedes Mal, wenn wir loggen?

(Ich weiß, dass ich die Metriken selbst ohne großes Problem machen könnte, aber hey, wofür ist StackOverflow?)


Ich bezweifle, dass Sie eine befriedigende Antwort von SO zu diesem Thema bekommen werden. Der Grund dafür ist, dass die Performance, insbesondere Szenarien dieses Typs, sehr anwendungsspezifisch sind.

Jemand kann mit einem schnellen Stoppuhr-Beispiel, das in Bezug auf rohe Millisekunden schneller ist, zurückschreiben. Aber ehrlich gesagt, das bedeutet nichts für Ihre Bewerbung. Warum? Es hängt stark von dem Nutzungsmuster in diesem speziellen Szenario ab. Zum Beispiel ...

  1. Wie viele Arten hast du?
  2. Wie groß sind deine Methoden?
  3. Machst du das für jede Methode oder nur für große?

Dies sind nur einige der Fragen, die die Relevanz eines Straight-Time-Benchmarks stark verändern werden.


Der Unterschied ist wahrscheinlich vernachlässigbar hinsichtlich der Anwendungsleistung. Aber der erste Ansatz, bei dem Sie den Typ cachen, sollte schneller sein. Lass uns gehen und testen.

Dieser Code zeigt Ihnen den Unterschied:

using System;

namespace ConsoleApplicationTest {
    class Program {
        static void Main(string[] args) {

            int loopCount = 100000000;

            System.Diagnostics.Stopwatch timer1 = new System.Diagnostics.Stopwatch();
            timer1.Start();
            Foo foo = new Foo();
            for (int i = 0; i < loopCount; i++) {
                bar.SomeMethod();
            }
            timer1.Stop();
            Console.WriteLine(timer1.ElapsedMilliseconds);

            System.Diagnostics.Stopwatch timer2 = new System.Diagnostics.Stopwatch();
            timer2.Start();
            Bar bar = new Bar();
            for (int i = 0; i < loopCount; i++) {
                foo.SomeMethod();
            }
            timer2.Stop();
            Console.WriteLine(timer2.ElapsedMilliseconds);

            Console.ReadLine();
        }
    }

    public class Bar {
        public void SomeMethod() {
            Logger.Log(this.GetType(), "SomeMethod started...");
        }
    }

    public class Foo {
        private static readonly Type myType = typeof(Foo); 
        public void SomeMethod() { 
            Logger.Log(myType, "SomeMethod started..."); 
        }
    }

    public class Logger {
        public static void Log(Type type, string text) {
        }
    }
}

Auf meiner Maschine ergab dies Ergebnisse von ca. 1500 Millisekunden für den ersten Ansatz und ca. 2200 Millisekunden für die Sekunde.

(Code und Timings korrigiert - doh!)


Das Verwenden des Felds ist der beste Weg, und es vermeidet die interne Wörterbuchsperre, die durch typeof () und GetType () verursacht, eine eindeutige Referenz beizubehalten.





performance