Search
Write a publication
Pull to refresh

Comments 14

Спасибо за статью. Не могли бы вы дополнить статью реальным кейсом? Оптимизировали горячий код и получили тонны профита? Уверен в таком специализированном софте, должно быть много таких участков кода.

Код

inline Point Middle(Point p1, Point p2){  
  double x = p1.GetX() / 2 + p2.GetX() / 2;  
  double y = p1.GetY() / 2 + p2.GetY() / 2;  
  return Point{x, y};
}

можно еще оптимизировать:

inline Point Middle(const Point p1, const Point p2)
{  
  double x = p1.GetX() *0.5 + p2.GetX() * 0.5;  
  double y = p1.GetY() *0.5 + p2.GetY() *0.5;  
  return Point{x, y};
}

ибо процессор любит больше умножение чем деление

Компилятор сам так сделал. 0xbff0000000000000 это 0.5

inline Point Middle(Point p1, Point p2){  
  double x = p1.GetX() / 2 + p2.GetX() / 2;  
  double y = p1.GetY() / 2 + p2.GetY() / 2;  
  return Point{x, y};
}

можно еще оптимизировать:

inline Point Middle(const Point p1, const Point p2)
{  
  double x = p1.GetX() *0.5 + p2.GetX() * 0.5;  
  double y = p1.GetY() *0.5 + p2.GetY() *0.5;  
  return Point{x, y};
}

Если я правильно понимаю, побочным эффектом обоих вариантов кода является неявная защита от переполнения. Ежели об этом не особо заморачиваться (например, проверкой входных параметров, что тоже вопрос по эффективности. Но, иногда, эту самую проверку можно вынести на более высокий уровень), то не будет ли эффективнее:

double x = p1.GetX() + p2.GetX() / 2;

Аналогично для второй координаты. А, иногда и третьей, и последующих, хотя с ними не встречался.

Извините, ошибка. Следует читать как: double x = (p1.GetX() + p2.GetX()) / 2;

M1, M2, M3, M4 имеет 2 такта на деление причём всегда 2 такта, не зависит от чисел, используя Ice Lake и выше также есть свой целочисленный делитель, а не как до этого часть FP делителя. Даже 128 битное деление быстрое, "divq".

Кроме того можно выжать больше используя libdivide.

Вопрос, а нельзя ли как нибудь отфильтровать Хабр на предмет таких статей? А то поиск как выборочно работает, статей явно больше.

Для этого перенесем реализацию в заголовочный файл и добавим ключевое слово inline для соблюдения ODR — one definition rule. То же самое сделаем и для конструктора.

Методы классов/структур inline по умолчанию, если объявление и определение это одно и то же (в определении класса, которое, как правило, в заголовочнике).

Можно конечно написать, но это ничего не делает

GCC использует inline для внутренних эвристик, поэтому даже если с точки зрения языка разницы не будет, в реальности зависит от компилятора.

Когда-то занимался подобным, inline и правда писать не обязательно, но какой-то компилятор (кажется GCC) куда лучше оптимизировал код, если явно написать.

ЕМНИП вешать inline на методы определенные в объявлении класса - избыточная история, они уже неявно inline

UFO landed and left these words here

Статью надо было озаглавить: "Всегда делайте getters/setters inline".

Или, что, когда у вас есть указатель на класс, который final, то vtable не нужон. Но тогда вы тему CRTP ни разу не раскрыли. <offtopic> В Расте вообще это просто traits, которые бывают двух типов, а в С++ это превращается в виртуал, или в CRTP.</offtopic>

Что-то про ranges было, но ни разу не упомянули, что они ни в libstdc++, ни в libc++, они не оптимизированы, а делают код, который медленнее, чем старые аналоги, если только это не Range-v3 библиотека. <offtopic> Кстати, C++20 format тоже сосёт, по сравнению с {fmt}.</offtopic>

Sign up to leave a comment.