Эффективность функции-члена, возвращающей std :: vector.size () в объектно-ориентированной среде

У меня есть класс, объявленный в prob.h таким образом:

struct A_s{
int a, b;
}

class A_c{
private:
std::vector<A_s> vec_of_A_s;
public:
int vec_of_A_s_size() const{return static_cast<int>(vec_of_A_s.size());}
}

С A_c A;//A is an object of class A_cгде-то еще в моей реализации .cpp файл, у меня есть следующая строка:

for(int i = 0; i < A.vec_of_A_s_size(); i++) {...//do loop stuff}

Я ЗНАЮ от дизайна моей программы, что A.vec_of_A_s_size() является инвариантным для цикла. Тем не менее, я действительно хочу избежать следующего (это громоздко):

int sz = A.vec_of_A_s_size();
for(int i = 0; i < sz; i++) {...//do loop stuff}

Могу ли я в достаточной мере и последовательно полагаться на компилятор, который не будет оценивать сборка выпуска с включенной оптимизацией (-O2) vec_of_A_s.size() каждый раз?

Вот что я уже пробовал вместе со своими вопросами:

(1) (Пожалуйста, см. Редактирование обновления ниже) Даже с отладочной сборкой, с опциями -fPIC -fno-strict-aliasing -fexceptions -g -std=c++14, глядя на вывод дизассемблера, vec_of_A_s.size() оценивается только один раз. Однако будет ли компилятор делать эту оптимизацию надежно последовательно? Есть ли известные исключения? Частично причина моего скептицизма и потребности в уверенности вытекает из следующего вопроса (2).

(2) Я посмотрел на связанный вопрос о SO: Проблема производительности для вектора :: размер () в цикле. Вопрос там напрямую оценивает размер вектора в цикле следующим образом:

for(int i = 0; i < vec_of_A_s.size(); i++) {...//do loop stuff}

В моем случае, вектор не доступен напрямую. Это частный член A_c и его размер может быть доступен только через функцию-член A.vec_of_A_s_size(), Таким образом, существует дополнительный уровень косвенности / перенаправления, который должен происходить внутри цикла for. Ответы в этой теме позволяют предположить, что компилятор действительно оптимизирует инвариант цикла. Но в случае (как выше), когда размер вектора не является прямо и публично доступным, будет ли компилятор надежно гарантировать оптимизацию инварианта цикла?

(3) В других смежных вопросах по таким вопросам, общий ответ, кажется, для профилирования программы. Если и когда я выполняю профилирование, что именно я должен искать, чтобы проверить эту конкретную оптимизацию? Этот код является частью большего кода числового анализа, и это определенно НЕ текущее узкое место. Тем не менее, было бы неплохо узнать, как это можно проверить в профилировщике. Извиняюсь, если этот вопрос (3) слишком широк. Я относительно новичок в профилировании. Но позволяют ли профилировщики профилировать одну функцию, скажем, функцию, которая содержит for цикл выше? Таким образом, я могу точно знать, где находится узкое место, так как оно относится к этой функции.


Изменить обновление:

На (1) НЕ верно, что отладочная сборка с указанными параметрами компилятора оптимизирует инвариант цикла. Я был неправ. При более глубоком копании оказывается, что функция действительно вызывается дважды.

0

Решение

Если ваш цикл вызывает неконстантный метод для вектора, то я бы с уверенностью сказал, что все ставки выключены.

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

Учитывая, что вы можете объявить более одной переменной в цикле for, если они одного типа, ввод sz в цикл кажется очевидной вещью. Или вы можете запустить цикл в обратном направлении?

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]