2016-02-12 5 views
5

Gibt es eine effizientere Art und Weise die folgende, etwas zu tun, fühlt sich einfach falsch daran? Ich bin auf der Suche nach der zeitsparendsten Art logarithmisch zu loggen.Logging logarithmisch 1, 10, 100, 1000, etc

public bool Read() 
    { 
     long count = Interlocked.Increment(ref _count); 
     switch (count) 
     { 
      case 1L: 
      case 10L: 
      case 100L: 
      case 1000L: 
      case 10000L: 
      case 100000L: 
      case 1000000L: 
      case 10000000L: 
      case 100000000L: 
      case 1000000000L: 
      case 10000000000L: 
      case 100000000000L: 
      case 1000000000000L: 
      case 10000000000000L: 
      case 100000000000000L: 
      case 10000000000000000L: 
      case 100000000000000000L: 
      case 1000000000000000000L: 
       _logger.LogFormattable(LogLevel.Debug, $"{count} Rows Read"); 
       break; 
     } 

     return _reader.Read(); 
    } 

Update:

Hier mein Mikro-Benchmark-Tests sind.

  • Method1: Übercoder Weg mit Zustand hält mit
  • Method2: Mein Weg mit der großen switch-Anweisung
  • Method3: Markus Weninger Weg mit der netten Math Funktion

Da für mich 100.000.000 Aufzeichnungen, die ohne Protokollierung gelesen werden, dauern ungefähr 20 Minuten, dann sind zusätzliche 4 Sekunden nichts. Ich gehe mit der schönen mathematischen Art, Dinge zu tun. Mathod3 gewinnt in meinem Szenario.

Run time for 100,000,000 iterations averaged over 100 attempts 

Method1 Max: 00:00:00.3253789 
Method1 Min: 00:00:00.2261253 
Method1 Avg: 00:00:00.2417223 

Method2 Max: 00:00:00.5295368 
Method2 Min: 00:00:00.3618406 
Method2 Avg: 00:00:00.3904475 

Method3 Max: 00:00:04.0637217 
Method3 Min: 00:00:03.2023237 
Method3 Avg: 00:00:03.3979303 
+0

@Dai das ist auf Gleitkomma, was hier nicht der Fall ist. Auch die Frage bezieht sich auf C#, nicht auf C++. Wenn Sie ein besseres, Duplikat haben, lassen Sie es mich wissen. –

+1

Die Verwendung einer 'switch'-Anweisung, wie Sie es tun, ist wirklich der schnellste Weg, dies zu tun, da es in eine Reihe von hashtable-Anweisungen auf Prozessorebene kompiliert wird, die blitzschnell sind. Während der Code "hässlich" ist (naja, ich denke, es ist irgendwie schön), denke ich, dass man ihn verbessern kann, indem man ihn auf eine separate Funktion ("IsExactlyPowerOf10 (Int64 n)") setzt und diese aus seiner "Read" -Funktion aufruft. – Dai

+0

Dank für das nette Benchmarking aller drei Methoden :) –

Antwort

8

Wenn die Leistung kein großes Problem ist, würde ich die folgenden

if(Math.Log10(count) % 1 == 0) 
    _logger.LogFormattable(LogLevel.Debug, $"{count} Rows Read"); 

This question besagt Folgendes:

Für Gleitkommazahlen, n% 1 == 0 ist typischerweise die Möglichkeit, zu überprüfen, ob etwas über den Dezimalpunkt hinausgeht.


Edit: meine Antwort zu vervollständigen, ist es auch möglich, den Überblick über die nächsten Protokollierung Wert zu halten, wie @ Übercoder in seiner Antwort geschrieben.

long nextLoggingValueForLogX = 1; 
if (count == nextLoggingValueForLogX) 
{ 
    nextLoggingValueForLogX *= 10; // Increase it by your needs, e.g., logarithmically by multiplying with 10 
    _logger.LogFormattable(LogLevel.Debug, $"{count} Rows Read"); 
} 

Doch diese Methode wird für jedes Protokoll mit einer neuen Variablen kommen, die nicht jedes Mal ausgeführt werden sollen. Dies führt zu zusätzlichen Code und zusätzlichen Arbeiten, wenn es threadsicher gemacht werden muss.

+0

ich werde einen Leistungstest von mir vs Ihnen tun und sehen, was schneller kommt, ich hoffe wirklich, dass es Ihr ist, weil es viel schöner ist. Auch wenn es ein wenig langsamer ist werde ich ich wahrscheinlich immer noch verwenden. Lassen Sie mich einige Performance-Tests durchführen, um zu sehen, ob ich das als Antwort markieren. –

+0

Ja, ich bin auch daran interessiert. ich hoffe, dass es für Sie funktioniert. –

3
static long logTrigger = 1; 


if (count == logTrigger) 
{ 
    logTrigger *= 10; 
    // do your logging 
} 
+0

ich wette, dein ist das schnellste, Ich werde Sie wissen lassen. Ich würde die statische obwohl vom Auslöser entfernen. –

+0

Ja, das wird mit Sicherheit die schnellste sein. Aber auf der anderen Seite, führt es eine neue Variable für jedes Protokoll, das logarithmisch ausgeführt werden soll Wahl man muss machen. –

+2

Ja, ich muss viel tun, um diesen Thread auch sicher zu machen, da es nicht so ist. –