Разница в производительности между доступом к локальным переменным и переменным членам класса - PullRequest
2 голосов
/ 25 ноября 2011

У меня есть следующий код в функции члена класса:

int state = 0;
int code = static_cast<int>(letter_[i]);
if (isalnum(code)) {
      state = testTable[state][0];
    } else if (isspace(code)) {
        state = testTable[state][2];
    } else if (code == OPEN_TAG) {
        state = testTable[state][3];
    } else if (code == CLOSE_TAG) {
        state = testTable[state][4];
    } else {
        state = testTable[state][1];
    }

    switch (state) {
    case 1: // alphanumeric symbol was read
        buffer[j] = letter_[i];
        ++j;
        break;
    case 2: // delimeter was read
        j = 0;
    //  buffer.clear();
        break;
    }

Однако, если состояние - это переменная-член класса, а не локальная, производительность значительно падает (~ 5 раз). Я читал о различиях в доступе к локальным переменным и членам класса, но в текстах обычно говорится, что это очень мало влияет на производительность.

Если это поможет: я использую компилятор MinGW GCC с опцией -O3.

1 Ответ

1 голос
/ 25 ноября 2011

Я не смог воспроизвести ваши наблюдения, тестируя на x86_64 как VS10, так и g ++. Локальный вариант немного быстрее, вероятно, из-за того, что Алан Стоукс описал в своем комментарии, но не более ~ 10%. Вы должны проверить время, постараться исключить любые другие проблемы, и лучше всего свести весь ваш код к очень простому тестовому прибору, который все еще показывает это поведение.

Мне кажется, мой тестовый сценарий очень неплохо напоминает ваш сценарий, по крайней мере, так, как вы его описали:

#include <iostream>
#include <boost/timer.hpp>

const int max_iter = 1<<31;
const int start_value = 65535;

struct UseMember
{
    int member;
    void foo()
    {
        for(int i=0; i<max_iter; ++i)
        {
            if(member%2)
                member = 3*member+1;
            else
                member = member>>1;
        }
        std::cout << "Value=" << member << std::endl;
    }
};

struct UseLocal
{
    void foo()
    {
        int local = start_value;
        for(int i=0; i<max_iter; ++i)
        {
            if((local%2)!=0) /* odd */
                local = 3*local+1;
            else /* even */
                local = local>>1;
        }
        std::cout << "Value=" << local << std::endl;
    }
};


int main(int argc, char* argv[])
{
    /* First, test using member */
    std::cout << "** Member Access" << std::endl;
    {
        UseMember bar;
        bar.member = start_value;
        boost::timer T;
        bar.foo();
        double e = T.elapsed();
        std::cout << "Time taken: " << e << "s" << std::endl;
    }

    /* Then, test using local */
    std::cout << "** Local Access" << std::endl;
    {
        UseLocal bar;
        boost::timer T;
        bar.foo();
        double e = T.elapsed();
        std::cout << "Time taken: " << e << "s" << std::endl;
    }
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...