2016-02-12 2 views
5

Есть ли более эффективный способ сделать следующее, что-то просто не так в этом нуждается? Я ищу наиболее эффективный способ регистрации логарифмически.Логарифмически логарифмически 1, 10, 100, 1000 и т. Д.

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:

Вот мои микро тесты тестов.

  • Method1: путь Übercoder с не отставать от состояния
  • method2: Мой пути с большим заявлением переключателя
  • method3: путь Маркуса Венингера с славным Math Function

Поскольку для меня 100000000 записи, считанные без регистрации, занимают около 20 минут, а дополнительные 4 секунды - ничто. Я собираюсь с прекрасным математическим способом делать что-то. Mathod3 побеждает в моем сценарии.

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

@ Дай, что на плавающей запятой, что здесь не так. Также возникает вопрос о C#, а не C++. Если у вас есть лучший, дубликат, дайте мне знать. –

+1

Использование оператора 'switch', как и вы, действительно является самым быстрым способом сделать это, поскольку он будет скомпилирован в ряд инструкций хэш-таблицы на уровне процессора, которые бывают молниеносно. Хотя код «уродливый» (ну, я думаю, это красиво), я думаю, вы можете улучшить его, переместив его на отдельную функцию («IsExactlyPowerOf10 (Int64 n)») и вызвав это из вашей функции «Чтение». – Dai

+0

Спасибо за хороший бенчмаркинг всех трех методов :) –

ответ

8

Если производительность не является большой проблемой, я бы использовал следующие

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

This question утверждает следующее:

Для чисел с плавающей точкой, п% 1 == 0 является обычно способ проверить, есть ли что-либо за десятичной точкой.


Edit: Для того, чтобы завершить свой ответ, также можно отслеживать следующее значение регистрации, а @ Übercoder писал в своем ответе.

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"); 
} 

Однако этот метод будет иметь новую переменную для каждого журнала, который не должен выполняться каждый раз. Это добавит дополнительный код, а также дополнительную работу, если он должен быть потокобезопасным.

+0

Я сделаю тест производительности своего против твоего и посмотрю, что получится быстрее, я действительно надеюсь, что это твое, потому что оно намного красивее. Даже если это будет немного медленнее, я буду вероятно, все еще использую его. Позвольте мне сделать некоторые тесты производительности, чтобы увидеть, могу ли я отметить это как ответ. –

+0

Да, я также заинтересован в этом. Надеюсь, что это сработает для вас. –

3
static long logTrigger = 1; 


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

Уверен, что ваш самый быстрый, я Да, вы знаете, я удалял бы статику, хотя бы с триггера. –

+0

Да, это наверняка будет самым быстрым, но с другой стороны, оно вводит новую переменную для каждого журнала, которая должна выполняться логарифмически. выбор нужно сделать. –

+2

Да, мне нужно много сделать, чтобы сделать эту нить безопасной, так как это не так. –

Смежные вопросы