2011-02-18 내용수정 >> 결론 4번
///////////////////////////////////////////////////////////////////////////////
std::string 간단히 속도 테스트를 해보았다..
테스트 방법은
vs 2008 에서 콘솔 프로젝트를 생성하고 설정은 기본으로 만들어진 그대로 진행하였다.
최적화는 기본으로 속도 최적화로 설정 되어있었다..
#include "stdafx.h" #include#include #include #include #pragma comment(lib, "Winmm") #define printLine(x) std::cout << x << std::endl class TimeLog { public: TimeLog( const std::string& msg = std::string() ) : mLogMessage(msg) { mStartTime = timeGetTime(); } ~TimeLog() { std::cout << std::setw(6) << timeGetTime() - mStartTime << "(ms) " << mLogMessage << std::endl; } private: std::string mLogMessage; int mStartTime; }; std::string retString1() {return "";} static std::string BlankStr; std::string retString2() {return BlankStr;} void main() { DWORD maxCount = 500000000; // std::string 초기화 테스트 // "" 를 넣어서 생성. { TimeLog log("initialize : using(\"\") "); for ( DWORD i = 0; i < maxCount; ++i ) { std::string testStr = ""; } } // std::string 초기화 테스트 // "" 를 넣지 않고 생성. { TimeLog log("initialize : default"); for ( DWORD i = 0; i < maxCount; ++i ) { std::string testStr; } } }
위와 같은 코드로 간단히 테스트를 실행해보았다..
우선 위의 코드는 생성자에 대한 속도 테스트..
maxCount = 200000000; // std::string 문자열 대입 속도 테스트 { std::string testStr; testStr.resize(1024); char* insertString = "abcdefghijklmnABCDEFGHIJKLMN"; TimeLog log("set data : char*"); for ( DWORD i = 0; i < maxCount; ++i ) { testStr = insertString; testStr.erase(); } } // std::string 문자열 대입 속도 테스트 { std::string testStr; testStr.resize(1024); std::string insertString = "abcdefghijklmnABCDEFGHIJKLMN"; TimeLog log("set data : std::string"); for ( DWORD i = 0; i < maxCount; ++i ) { testStr = insertString; testStr.erase(); } }
위의 코드는 데이터를 넣을때의 타입에따른 속도테스트..
//------------------------------------------------// maxCount = 200000000; // 함수에서 std::string을 리턴할때 테스트 // std::string retString1() {return "";} { std::string testStr; testStr.resize(1024); TimeLog log("func return std::string : using(\"\")"); for ( DWORD i = 0; i < maxCount; ++i ) { testStr = retString1(); testStr.erase(); } } // 함수에서 std::string을 리턴할때 테스트 // static std::string BlankStr; // std::string retString2() {return BlankStr;} { std::string testStr; testStr.resize(1024); TimeLog log("func return std::string : static std::string"); for ( DWORD i = 0; i < maxCount; ++i ) { testStr = retString2(); testStr.erase(); } }
위의 테스트는 함수에서 std::string을 리턴을때
return을 무엇으로 하느냐에 따른 속도 테스트...
maxCount = 20000000; // 문자열 지우기 속도 테스트 // "" { std::string insertStr; insertStr.assign(2048,'a'); TimeLog log("string clear : using(\"\")"); for ( DWORD i = 0; i < maxCount; ++i ) { std::string testStr = insertStr; testStr = ""; } } // 문자열 지우기 속도 테스트 // clear { std::string insertStr; insertStr.assign(2048,'a'); TimeLog log("string clear : clear()"); for ( DWORD i = 0; i < maxCount; ++i ) { std::string testStr = insertStr; testStr.clear(); } } // 문자열 지우기 속도 테스트 // erase { std::string insertStr; insertStr.assign(2048,'a'); TimeLog log("string clear : erase()"); for ( DWORD i = 0; i < maxCount; ++i ) { std::string testStr = insertStr; testStr.erase(); } }
std::string내부의 데이터를 지우는 방법에 따른 속도 테스트 ..
maxCount = 20000000; // 문자열 재사용을 위함 문자열 비우기 테스트 { std::string insertStr; insertStr.assign(2048,'a'); std::string testStr; TimeLog log("string clear for reuse : using(\"\")"); for ( DWORD i = 0; i < maxCount; ++i ) { testStr = insertStr; testStr = ""; } } // 문자열 재사용을 위함 문자열 비우기 테스트 { std::string insertStr; insertStr.assign(2048,'a'); std::string testStr; TimeLog log("string clear for reuse : clear()"); for ( DWORD i = 0; i < maxCount; ++i ) { testStr = insertStr; testStr.clear(); } } // 문자열 재사용을 위함 문자열 비우기 테스트 { std::string insertStr; insertStr.assign(2048,'a'); std::string testStr; TimeLog log("string clear for reuse : erase()"); for ( DWORD i = 0; i < maxCount; ++i ) { testStr = insertStr; testStr.erase(); } }
위 테스트는...
std::string 객체를 재사용 한다고 생각할때 어떤식의 데이터 초기화가 좋을것인가?
테스트 했던 소스 코드..
아래는 속도 테스트 결과이다...
결과는..
1. std::string 객체 생성시에는 알아서 초기화를 해주기때문에
"" << 를 넣어서 해주면 오히려 느려진다..
2. 데이터를 넣을때도 char* 같은 타입으로 넣는것보단 같은 타입인 std::string을 넣는게 빠른다..
3. 함수에서 std::string을 리턴 할때에도 문자열 길이가 0인 문자를 리턴할때
"" 로 리턴 하는것 보단 글로벌 변수나 static 변수로 미리 만들어 놓은 길이0짜리 std::string 을 리턴하는게 빠르다.
4. std::string 객체 내부의 문자열을 지울때는 "" 로 지우나 erase()로 지우나 별 차이가 없다..
clear 함수는 내부적으로 erase(begin(),end()) 방식으로 동작하고있다...
void __CLR_OR_THIS_CALL clear();
iterator __CLR_OR_THIS_CALL erase(const_iterator _First, const_iterator _Last);
_Myt& __CLR_OR_THIS_CALL erase(size_type _Off = 0, size_type _Count = npos);
이 함수는 결과적으로 위와 같이 3개의 함수 호출 순서를 가지므로 erase(); << 이방식보다 비효율적이다.
클래스의 맴버 객체로 존재하는 std::string들은 메모리 반환(capacity줄이기)을 위해
std::string().swap(str); 방식으로 지워놓는것도 메모리 상의 효율은 더 좋아보인다. (자주 호출된다면 안쓰는게좋을듯)
5. 같은 std::string 객체 재사용의 관점에서 본다면..
""로 지우고 재사용하나 erase로 지우고 하나 별 차이는 없어보인다..
하지만 바로 재사용을 하는데 clear로 지우고 재사용을 하게되면..
버퍼의 사이즈가 초기화된 상황에서 다시 버퍼를 늘려야되는 상황이 생기게 되므로 좋지 않겠다..
'프로그래밍' 카테고리의 다른 글
stl std::remove의 이해와 활용 (0) | 2011.02.18 |
---|---|
std::string Ogre::String 생성자의 함수호출 낭비 (0) | 2011.02.01 |
Visual Studio 에서 명령 창 도구 사용하는 방법 (0) | 2011.01.28 |
STL 컨테이너들의 사이즈를 한번 출력해 봤다.. (0) | 2011.01.24 |
Windows CPU 효율 향상을 위한 프로그래밍시 데이터 정렬 (0) | 2011.01.21 |
댓글