글수 69
제가 이 코드로 테스트 했을 때는 결과가 다음과 같았습니다.
Debug 빌드:
strlen8 = 3233, time=0.086509
strlen32 = 3233, time=0.041553
strlen = 3233, time=0.011826
Release 빌드:
strlen8 = 3233, time=0.033875
strlen32 = 3233, time=0.019381
strlen = 3233, time=0.033616
(단위: 초)
(몇 번 테스트 한 것 중 아무거나 뽑아온 것)
Visual C++ 7.1에서 Win32 빈 프로젝트 만들고 그냥 작성한 것입니다.
제가 테스트 할 때 디스어셈블리 창으로 확인해본 결과, strlen8/32 함수는 인라인 처리 되었었습니다.
이 게시판은 소스 코드 업로드가 안 되므로 부득불 테스트용 전체 코드를 그냥 여기에 적습니다.
[code]
#include <stdio.h>
#include <windows.h>
int strlen8(const char *str)
{
const char *count = str;
while (*count) {
count++;
}
return (int)(count - str);
}
int strlen32(const char *str)
{
const int *count = (int *)str;
while (1) {
if ((*count & 0x000000ff) == 0) break;
if ((*count & 0x0000ff00) == 0) { str--; break; }
if ((*count & 0x00ff0000) == 0) { str-=2; break; }
if ((*count & 0xff000000) == 0) { str-=3; break; }
count++;
}
return (int)((char *)count - str);
}
// 시간 측정을 위한 것들
struct PerformanceCounter {
LARGE_INTEGER StartTime;
LARGE_INTEGER EndTime;
};
void StartMeasure(PerformanceCounter &time)
{
time.StartTime.QuadPart = 0;
time.EndTime.QuadPart = 0;
QueryPerformanceCounter(&time.StartTime);
}
void EndMeasure(PerformanceCounter &time)
{
QueryPerformanceCounter(&time.EndTime);
}
double GetElapsedTime(PerformanceCounter &time)
{
LARGE_INTEGER Freq;
QueryPerformanceFrequency(&Freq);
return ((double)time.EndTime.QuadPart - (double)time.StartTime.QuadPart) / (double)Freq.QuadPart;
}
int main()
{
char text[] = "왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
;
PerformanceCounter time;
int i;
int len;
// strlen8 측정 시작
StartMeasure(time);
for (i=0; i<10000; i++) {
len = strlen8(text);
}
EndMeasure(time);
// 측정 끝
printf("strlen8 = %d, time=%f\n", len, GetElapsedTime(time));
// strlen32 측정 시작
StartMeasure(time);
for (i=0; i<10000; i++) {
len = strlen32(text);
}
EndMeasure(time);
// 측정 끝
printf("strlen32 = %d, time=%f\n", len, GetElapsedTime(time));
// strlen 측정 시작
StartMeasure(time);
for (i=0; i<10000; i++) {
len = (int)strlen(text);
}
EndMeasure(time);
// 측정 끝
printf("strlen = %d, time=%f\n", len, GetElapsedTime(time));
return 0;
}
[/code]
Debug 빌드:
strlen8 = 3233, time=0.086509
strlen32 = 3233, time=0.041553
strlen = 3233, time=0.011826
Release 빌드:
strlen8 = 3233, time=0.033875
strlen32 = 3233, time=0.019381
strlen = 3233, time=0.033616
(단위: 초)
(몇 번 테스트 한 것 중 아무거나 뽑아온 것)
Visual C++ 7.1에서 Win32 빈 프로젝트 만들고 그냥 작성한 것입니다.
제가 테스트 할 때 디스어셈블리 창으로 확인해본 결과, strlen8/32 함수는 인라인 처리 되었었습니다.
이 게시판은 소스 코드 업로드가 안 되므로 부득불 테스트용 전체 코드를 그냥 여기에 적습니다.
[code]
#include <stdio.h>
#include <windows.h>
int strlen8(const char *str)
{
const char *count = str;
while (*count) {
count++;
}
return (int)(count - str);
}
int strlen32(const char *str)
{
const int *count = (int *)str;
while (1) {
if ((*count & 0x000000ff) == 0) break;
if ((*count & 0x0000ff00) == 0) { str--; break; }
if ((*count & 0x00ff0000) == 0) { str-=2; break; }
if ((*count & 0xff000000) == 0) { str-=3; break; }
count++;
}
return (int)((char *)count - str);
}
// 시간 측정을 위한 것들
struct PerformanceCounter {
LARGE_INTEGER StartTime;
LARGE_INTEGER EndTime;
};
void StartMeasure(PerformanceCounter &time)
{
time.StartTime.QuadPart = 0;
time.EndTime.QuadPart = 0;
QueryPerformanceCounter(&time.StartTime);
}
void EndMeasure(PerformanceCounter &time)
{
QueryPerformanceCounter(&time.EndTime);
}
double GetElapsedTime(PerformanceCounter &time)
{
LARGE_INTEGER Freq;
QueryPerformanceFrequency(&Freq);
return ((double)time.EndTime.QuadPart - (double)time.StartTime.QuadPart) / (double)Freq.QuadPart;
}
int main()
{
char text[] = "왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
"왜날break!왜날break!왜날break!왜날break!왜날break!왜날break!\n"
;
PerformanceCounter time;
int i;
int len;
// strlen8 측정 시작
StartMeasure(time);
for (i=0; i<10000; i++) {
len = strlen8(text);
}
EndMeasure(time);
// 측정 끝
printf("strlen8 = %d, time=%f\n", len, GetElapsedTime(time));
// strlen32 측정 시작
StartMeasure(time);
for (i=0; i<10000; i++) {
len = strlen32(text);
}
EndMeasure(time);
// 측정 끝
printf("strlen32 = %d, time=%f\n", len, GetElapsedTime(time));
// strlen 측정 시작
StartMeasure(time);
for (i=0; i<10000; i++) {
len = (int)strlen(text);
}
EndMeasure(time);
// 측정 끝
printf("strlen = %d, time=%f\n", len, GetElapsedTime(time));
return 0;
}
[/code]
2007.10.23 21:29:32 (*.128.171.106)
strlen만 디버그 모드가 더 빠르군요..
strlen()은 디버그 모드나 릴리즈 모드나 코드의 차이가 없으므로 둘 사이의 속도 차이는 strlen보다 다른데 있을 것 같습니다. 다른 쪽에서 캐싱 등의 영향을 받아서 차이가 생긴게 아닌가 싶습니다..
직접 작성하신 strlen8, 32의 경우에는 릴리즈 모드에서 코드 최적화가 일어나므로 더 빨라진 것 같네요..
strlen()은 디버그 모드나 릴리즈 모드나 코드의 차이가 없으므로 둘 사이의 속도 차이는 strlen보다 다른데 있을 것 같습니다. 다른 쪽에서 캐싱 등의 영향을 받아서 차이가 생긴게 아닌가 싶습니다..
직접 작성하신 strlen8, 32의 경우에는 릴리즈 모드에서 코드 최적화가 일어나므로 더 빨라진 것 같네요..
2007.10.23 21:49:12 (*.234.76.109)
최적화 옵션 때문인 것 같습니다.
디버그 모드는 편의를 위해 모든 인라인 함수를 인라인으로 처리하지 않습니다.
그래서 일단 strlen 함수가 strlen.asm에 있는 어셈블리 버전으로 호출됩니다. (이 함수는 32비트씩처리합니다.)
그런데 릴리즈 모드로 오면 최적화 옵션에 따라 strlen 함수를 내장 함수로 처리해서 인라인 확장을 시켜버리는데... 이게 8비트씩 처리하는 코드가 나오더군요.
#pragma function(strlen) 을 이용해서 strlen을 내장 함수로 처리하지 않으면, 모두 똑같이 strlen.asm의 함수를 호출하기 때문에 디버그 모드와 릴리즈 모드의 속도 차이가 없게 됩니다. (물론 두 경우 모두 빨라지는 쪽으로 같아집니다.)
#pragma function(strlen)을 써보세요.
여튼 이것으로 봐도 32비트 단위로 처리하는게 훨씬 빠르다는 걸 알 수가 있군요.
디버그 모드는 편의를 위해 모든 인라인 함수를 인라인으로 처리하지 않습니다.
그래서 일단 strlen 함수가 strlen.asm에 있는 어셈블리 버전으로 호출됩니다. (이 함수는 32비트씩처리합니다.)
그런데 릴리즈 모드로 오면 최적화 옵션에 따라 strlen 함수를 내장 함수로 처리해서 인라인 확장을 시켜버리는데... 이게 8비트씩 처리하는 코드가 나오더군요.
#pragma function(strlen) 을 이용해서 strlen을 내장 함수로 처리하지 않으면, 모두 똑같이 strlen.asm의 함수를 호출하기 때문에 디버그 모드와 릴리즈 모드의 속도 차이가 없게 됩니다. (물론 두 경우 모두 빨라지는 쪽으로 같아집니다.)
#pragma function(strlen)을 써보세요.
여튼 이것으로 봐도 32비트 단위로 처리하는게 훨씬 빠르다는 걸 알 수가 있군요.

유니코드, crt static link에서 결과는
debug
strlen8 = 3233, time=0.095880
strlen32 = 3233, time=0.041744
strlen = 3233, time=0.007968
release
strlen8 = 3233, time=0.018707
strlen32 = 3233, time=0.014282
strlen = 3233, time=0.013899
왜 디버그에서 더 빠른걸까요 ㅋㅋㅋ