[C++] char*とstd::stringのアクセス速度と最適化の影響

선 결론

컴파일러의 최적화는 우수하므로, 그냥 std::string 을 사용하자. 다만, 명시적인 최적화 옵션 지정은 필수.

motivation

C 언어로 쓰여진 프로그램을 C++로 다시 쓸 때에 char* 로 다루고 있는 문자열을 std::string로 다루도록 했다. 안전성・편리성의 관점에서는 std::string, 실행 속도는 char*쪽이 빠르다.

실제로 어느 정도 영향이 나는지를 조사하고 싶었다. 파일로부터 읽어 들인 문자열을 1 문자 단위로 읽어 가는 프로그램으로 문자열에 대해 어떠한 조작을 하는 것보다는 각 문자에 액세스하는 시간을 측정한다.

테스트 코드

측정을 위해 다음 코드를 준비했다.

#include <iostream>
#include <chrono>
#include <string>

using namespace std;

int main()
{
        chrono::high_resolution_clock::time_point sstart, send, cstart, cend;
        long long l;
        l = 0;
        sstart = chrono::high_resolution_clock::now();
        for (size_t i = 0; i < 10000000; i++)
        {
                string s = "Hello, world!";
                for (size_t i = 0; i < s.length(); i++)
                {
                        if (s[i] == 'l')
                        {
                                l += 3;
                        }
                        else
                        {
                                l++;
                        }
                }
        }
        send = chrono::high_resolution_clock::now();

        cout << l << endl;
        double stime = static_cast<double>(chrono::duration_cast<chrono::microseconds>(send - sstart).count() / 1000.0);
        printf("string : %lf[ms]\n", stime);

        l = 0;
        cstart = chrono::high_resolution_clock::now();
        for (size_t i = 0; i < 10000000; i++)
        {
                char *c = "Hello, world!";
                while (*c)
                {
                        if (*c == 'l')
                        {
                                l += 3;
                        }
                        else
                        {
                                l++;
                        }
                        c++;
                }
        }
        cend = chrono::high_resolution_clock::now();

        cout << l << endl;
        double ctime = static_cast<double>(chrono::duration_cast<chrono::microseconds>(cend - cstart).count() / 1000.0);
        printf("char* : %lf[ms]\n", ctime);
        return 0;
}

적당하다고는 해도 아래 사항에 주의했다.

string변수를 생성하는 처리는 비교적 무겁기 때문에 string에 다소 불리한 프로그램이지만 결과적으로는 이 프로그램에서 문제 없을 것 같다.

최적화 옵션

gcc에서는 최적화 옵션을 -O 지정하여 최적화 정도를 지정할 수 있다.

측정 결과

image.png