[C++]문자열 함수 최적화

haeryong·2023년 7월 29일
0

1. 성능 최적화

0. 원본 코드

std::string remove_ctrl(std::string s){
	std::string result;
    for(int i = 0; i < s.length(); ++i){
    	if(s[i] > 0x20)
        	result = result + s[i];
    }
}

result : 24.8 us

1. += 연산자 사용.
기존의 코드는 매번 임시 문자열 객체를 생성함.

result += s[i];

result : 1.62 us

2. reserve() 사용

result.reserve(s.length());

result : 1.47 us

3. call by reference

std::string remove_ctrl(const std::string& s){
	...
}

result : 1.60 us
2번에 비해 시간이 늘어났는데, 이는 s가 참조이기때문에 매 루프마다 s를 역참조하느라 성능이 저하된 것임.

4. iterator 사용 + s.end() 미리 초기화

for(auto it = s.begin(), end = s.end(); it != end; ++it){
	if (*it >= 0x20)
    	result += *it;
}

result : 1.04 us

5. out parameter(복사 생성을 생략하는 방법 중 하나)

void remove_ctrl(const std::string& s, std::string& result){
	...
}

result : 1.02 us

6. c style

void remove_ctrl(const char* src, char* dst, size_t size){
	for(size_t i = 0; i < size; ++i){
    	if(src[i] >= 0x20)
        	*dst++ = src[i];
    }
}

result : 0.15 us
함수 호출을 없애고, cache locality를 향상시킨 결과.

2. 알고리즘 최적화

7. break, substr

std::string remove_ctrl(std::string s){
	std::string result;
    for(size_t b = 0, i = b, e = s.length(); b < e ; b = i + 1){
    	for (i = b; i < e; ++i){
        	if (s[i] < 0x20)
            	break;
        }
        result = result + s.substr(b, i - b);
    }
}

result : 2.91 us

8. break, append

result = result + s.substr(b, i - b);

result : 0.65 us
해당 함수에 2~5번을 적용하면 0.43 us까지 호출 시간이 감소한다.

9. erase

std::string romove_ctrl(std::string s){
	for(size_t i = 0; i < s.length();){
    	if(s[i] < 0x20)
        	s.erase(i, 1);
        else
        	++i;
    }
    return s;
}

result : 0.81 us

1개의 댓글

comment-user-thumbnail
2023년 7월 29일

정보 감사합니다.

답글 달기