size_t strlen_b(const char* s) // 1132 clocks // 137995 clocks
{
const char* o = s;
while(*s++);
return s - o - 1;
}
size_t strlen_d(const char* s) // 1129 clocks // 94742 clocks
{
size_t* p = (size_t*)s;
while((*p & 0x000000FF) && (*p & 0x0000FF00) && (*p & 0x00FF0000) && (*p & 0xFF000000)) p++;
if(!(*p & 0x000000FF)) return size_t((const char*)p - s);
if(!(*p & 0x0000FF00)) return size_t((const char*)p - s + 1);
if(!(*p & 0x00FF0000)) return size_t((const char*)p - s + 2);
return size_t((const char*)p - s + 3);
}
문자열의 길이를 리턴하는 두 함수다.
첫번째 strlen_b 는 1바이트 단위로 내용을 비교한다.
루프 안을 최적화 하기 위해 한 칸 지나쳐 갔다 마지막에 정산하는게 특징.
VC++ 기본 strlen 과 구조는 같다고 보면 된다. (속도를 재 봤는데 같다)
두번째 strlen_d 는 4바이트 단위로 내용을 비교한다. (예제에서 유니코드 지원을 바라진 말아줘)
루프 안에선 포인터 변수 p 를 증가시키는 이외의 어떠한 쓰기 연산도 하지 않는다.
함수 이름 옆 comment에 "Hello world" 문자열의 길이(11 문자 + NULL 문자) 를 계산한 것과
긴 문자열(99999 문자 + NULL 문자) 를 계산하는데 걸린 소요시간을 기록해 뒀다.
10만 바이트를 처리하는 루프에서 10만 클럭을 소요하지 않는다.
내 운영체제가 64bit라 32bit 컴파일의 결과가 만족스러운 속도는 아닐테지만 : )
이것이 pipeline 과 system word 단위 연산의 묘미.
p.s. 그러나 2번 함수도 더 최적화 할 수 있지롱.
유니코드 내놓으라는
시져시져~
COM의 BSTR(Basic String) 쓰는 게 젤 낫죠 ㅋㄷㅋㄷ strlen()이 O(1)임. 길이 정보를 prefix로 가지고 있어서...
ㅋㄷㅋㄷ 만들때 느리다는건 함정.
여러번 읽는다는 가정하엔 그 말이 맞앙.
http://dblack.tk
커뮤니티 사이트 입니다 많은 이용 부탁 드립니다.