내가 짧은 문자열 리터럴 문자열 다음 코드 예제에 설명 된 방법 비교 strcmp와의 호출에 필요한 오버 헤드를 원하지 않는 경우 :어떻게 문자 짧은 문자열로 문자열을 비교 효과적으로
#ifdef LITTLE_ENDIAN //little-endian-addressing
#define BytesAsDWord_M(a, b, c, d)\
((ulong) ((a) | ((b) << 8) | ((ulong) (c) << 16) | ((ulong) (d) << 24)))
#define BytesAsWord_M(a, b)((ushort) ((a) | ((b) << 8)))
#else //LITTLE_ENDIAN //little-endian-addressing
#define BytesAsDWord_M(a, b, c, d)\
((ulong) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24)))
#define BytesAsWord_M(a, b) ((ushort) ((b) | ((a) << 8)))
#endif //LITTLE_ENDIAN //little-endian-addressing
bool AbsCompare(char* chr_p)
//compare string with "abs"
{
if (*((ulong*) &chr_p[1]) ==
BytesAsDWord_M('a', 'b', 's', '\0'))
return true;
return false;
}
을
gcc는 최적화 옵션을 사용하지 않고 컴파일하는 한이 예제를 컴파일합니다.
는 "엄격한 앨리어싱 규칙을 깰 것이다 타입 punned 포인터를 역 참조" 심지어 -O3로 최적화하는 것은 예 효과적 코드 발생하지 않습니다가 보여 :
최적화 내가 경고를 활성화//abstest.c
#include <string.h>
typedef unsigned long ulong;
typedef unsigned short ushort;
#if BYTE_ORDER == LITTLE_ENDIAN //little-endian-addressing
#define BytesAsDWord_M(a, b, c, d)\
((ulong) ((a) | ((b) << 8) | ((ulong) (c) << 16) | ((ulong) (d) << 24)))
#define BytesAsWord_M(a, b)((ushort) ((a) | ((b) << 8)))
#else //BYTE_ORDER == LITTLE_ENDIAN //little-endian-addressing
#define BytesAsDWord_M(a, b, c, d)\
((ulong) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24)))
#define BytesAsWord_M(a, b) ((ushort) ((b) | ((a) << 8)))
#endif //BYTE_ORDER == LITTLE_ENDIAN //little-endian-addressing
int AbsCompare1(char* chr_p)
{
return *(ulong*) chr_p == BytesAsDWord_M('a', 'b', 's', '\0');
}
int AbsCompare2(char* chr_p)
{
return strcmp(chr_p, "abs");
}
int main(int argc __attribute__((unused)), char ** argv)
{
int i;
int j;
i = AbsCompare1(argv[0]);
j = AbsCompare2(argv[0]);
return i + j;
}
objdump를 -d -Mintel abstest :
080483d0 <AbsCompare1>:
80483d0: 55 push ebp
80483d1: 89 e5 mov ebp,esp
80483d3: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
80483d6: 5d pop ebp
80483d7: 81 38 61 62 73 00 cmp DWORD PTR [eax],0x736261
80483dd: 0f 94 c0 sete al
80483e0: 0f b6 c0 movzx eax,al
80483e3: c3 ret
080483f0 <AbsCompare2>:
80483f0: 55 push ebp
80483f1: 0f b6 0d 5c 85 04 08 movzx ecx,BYTE PTR ds:0x804855c
80483f8: 89 e5 mov ebp,esp
80483fa: 8b 55 08 mov edx,DWORD PTR [ebp+0x8]
80483fd: 0f b6 02 movzx eax,BYTE PTR [edx]
8048400: 29 c8 sub eax,ecx
8048402: 75 2b jne 804842f <AbsCompare2+0x3f>
8048404: 0f b6 42 01 movzx eax,BYTE PTR [edx+0x1]
8048408: 0f b6 0d 5d 85 04 08 movzx ecx,BYTE PTR ds:0x804855d
804840f: 29 c8 sub eax,ecx
8048411: 75 1c jne 804842f <AbsCompare2+0x3f>
8048413: 0f b6 42 02 movzx eax,BYTE PTR [edx+0x2]
8048417: 0f b6 0d 5e 85 04 08 movzx ecx,BYTE PTR ds:0x804855e
804841e: 29 c8 sub eax,ecx
8048420: 75 0d jne 804842f <AbsCompare2+0x3f>
8048422: 0f b6 42 03 movzx eax,BYTE PTR [edx+0x3]
8048426: 0f b6 15 5f 85 04 08 movzx edx,BYTE PTR ds:0x804855f
804842d: 29 d0 sub eax,edx
804842f: 5d pop ebp
8048430: c3 ret
직접이 짧은 문자를 비교하는 가능성이 특히 "& chr_p [1]"과 같은 임의의 인덱스에서 chr_p를 비교하기를 원하기 때문에 조합에 chr_p를 삽입하지 않아도됩니까?
빅 엔디안 아키텍처와 리틀 엔디안 아키텍처를 모두 대상으로하고 있지만 정렬 문제는 고려하지 않은 것으로 나타났습니다. '& chr_p [1]'과 같은 표현식은 어떤 점에서 비 단어 정렬 주소로 거의 확실하게 평가 될 것입니다. –
... 내가 아는 한 성능 제한 만있을 것입니다. – Wosh
@Wosh 일부 아키텍처에서는 액세스가 잘못 정렬되어 하드웨어 예외가 발생합니다. –