Сравнение кода и производительность

#java #performance

#java #Производительность

Вопрос:

В реализации высокопроизводительной библиотеки я увидел этот код

 double meanQ=0; 
int counter=0;
for(...){
    //some cycle with many iterations where meanQ and counter are incremented
}
meanQ /= (double)counter   0.001D;
  

Последняя строка выглядит для меня запутанной. Я бы просто сделал

 if(counter>0)
    meanQ /= counter;
  

Когда counter есть 0 , тогда meanQ также 0 есть , в противном случае оно делится на counter . Это также (немного) более точное среднее значение, нет приведений, его проще понять. Afaik, the if и сумма должны иметь одинаковую производительность, но я не могу проверить это на своей машине прямо сейчас.

Есть ли разница между обоими подходами? Является ли текущая версия библиотеки более эффективной или есть какие-либо другие причины выбрать ее по моему предложению?

Комментарии:

1. Ну, приведение там определенно не нужно. int double всегда дает double . Суффикс D также является излишним. Это совсем не способствует доверию к качеству библиотеки 🙂

2. Попробуйте правильное решение ( if ... ) и протестируйте обе версии. Имеет ли это значение?

3. Здесь это не так, поскольку по сравнению с циклом производительность незначительна. В основном я хотел получить ответ для дальнейшего использования. Однако у меня нет машины для тестирования на atm, поэтому я не могу их сравнить

Ответ №1:

Если meanQ /= (double)counter 0.001D; находится внутри цикла, то этот код выполняется быстрее, чем при использовании последнего кода:

  if(counter>0)
    meanQ /= counter;  
  

в цикле.

Это связано с тем, что для каждой итерации ему необходимо проверять счетчик на 0, и наличие if() будет иметь большое значение.

Сумма и if() не будут иметь одинаковой сложности.

Комментарии:

1. операции с плавающей запятой (особенно с двойной точностью) выполняются относительно медленно, поэтому я предполагаю, что вы ошибаетесь.

2. Я считаю, что на современных процессорах операции с плавающей запятой выполняются не медленнее, поскольку существуют векторные регистры, которые выполняют 4 или 8 операций с плавающей запятой за цикл. Если устройство не имеет действительно ограниченных ресурсов, таких как встроенная система, if() будет более значительным в снижении производительности по сравнению, имхо.

3. Однако это выходит if за рамки. Я отредактировал вопрос для ясности.

4. Кроме того, даже если предположить, что операции с плавающей запятой выполняются так же быстро, как и обычные операции, я предполагаю if , что они будут иметь аналогичную производительность из-за прогнозирования ветвлений . Хотя это всего лишь гипотетический момент: P

5. Извините, но я не могу согласиться с вашим утверждением, что «этот код лучше». Это может быть быстрее, но результат неверный.