Вопрос

string strLine;//not constant
int index = 0;
while(index < strLine.length()){//strLine is not modified};

сколько раз strLine.length() оценивается

нужно ли использовать nLength с <=>, назначенным <=> непосредственно перед циклом

Это было полезно?

Решение

length будет оцениваться каждый раз, когда вы проходите через цикл, однако, поскольку O(1) является постоянным временем (<=>), это не имеет большого значения, и добавление переменной для хранения этого значения, вероятно, будет незначительным эффект с небольшим ударом по читаемости кода (а также разрывом кода, если строка когда-либо изменена).

Другие советы

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

Каждый раз, когда он вызывается ... (каждый во время оценки). Если вы не меняете длину строки, вам лучше использовать временную переменную, например:

string strLine;
int stringLength = strLine.length();
int index = 0;
while(index < stringLength);

Я думаю, что в этом скрывается второй вопрос, и это &, какая реализация более понятна? "

Если семантически вы подразумеваете, что длина strLine никогда не изменяется внутри тела цикла, сделайте это очевидным, назначив переменную с хорошо именованным именем. Я бы даже сделал это const. Это дает понять другим программистам (и вам самим), что значение сравнения никогда не меняется.

С другой стороны, это облегчает просмотр значения этого значения, когда вы проходите через код в отладчике. Hover-over работает намного лучше на локальном, чем на вызов функции.

Говоря, & оставьте это как вызов функции; компилятор оптимизирует его " мне кажется преждевременной пессимизацией. Несмотря на то, что length () равен O (1), если он не встроен (вы не можете гарантировать, что оптимизации не отключены), это все же нетривиальный вызов функции. Используя локальную переменную, вы уточняете свое значение и получаете, возможно, нетривиальную оптимизацию производительности.

Делайте то, что делает ваши намерения наиболее ясными.

strLine.length () будет оцениваться, в то время как (i < strLine.length ())

Сказав, что если строка постоянная, большинство компиляторов оптимизируют это (с правильными настройками).

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

string strLine;//not constant
int index = 0;
const int strLenght = strLine.Length();
while(index < strLine.length()){//strLine is not modified};

Скорее всего, сам по себе компилятор выполняет эти оптимизации при доступе к методу Length ().

Изменить: моя сборка немного ржавая, но я думаю, что оценка происходит только один раз. Учитывая этот код:

int main()
{
    std::string strLine="hello world";

    for (int i=0; i < strLine.length(); ++i)
    {
        std::cout << strLine[i] <<std::endl;
    }
}

Создает эту сборку:

    for (int i=0; i < strLine.length(); ++i)
0040104A  cmp         dword ptr [esp+20h],esi 
0040104E  jbe         main+86h (401086h)

Но для этого кода

 std::string strLine="hello world";
 const int strLength = strLine.length();
 for (int i=0; i < strLength ; ++i)
 {
    std::cout << strLine[i] <<std::endl;
 }

генерирует это:

   for (int i=0; i < strLength ; ++i)
0040104F  cmp         edi,esi 
00401051  jle         main+87h (401087h) 

Та же самая сборка генерируется, если не используется const квалификатор, поэтому в этом случае это не имеет значения.

Пробовал с VSC ++ 2005

Как уже говорилось, поскольку функция string::length, скорее всего, полностью определена в заголовке и должна иметь значение O (1), почти наверняка вы получите доступ к простому члену и сможете встроиться в ваш код. Поскольку вы не объявляете строку как volatile, компилятору разрешается представить, что никакой внешний код не собирается ее изменять, и оптимизировать вызов для доступа к одной памяти и оставить значение в регистре, если он обнаружит, что это хорошая идея.

Собирая и кэшируя значение самостоятельно, вы увеличиваете вероятность того, что компилятор сможет сделать то же самое. Во многих случаях компилятор даже не генерирует код для записи длины строки в стек, а просто оставляет ее в регистре. Конечно, если вы вызываете разные функции, которые компилятор не может встроить, тогда значение должно быть записано в стек, чтобы вызовы функций не перемещались по регистру.

Поскольку вы не меняете строку, не следует ли использовать

const string strLine;

Просто потому, что тогда компилятор получает больше информации о том, что может и что нельзя изменить - хотя точно не знаю, насколько умным может быть компилятор C ++.

strLine.length() будет оцениваться каждый раз, когда вы проходите цикл.

Вы правы в том, что было бы эффективнее использовать nLength, особенно если strLine длинная.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top