#include <iostream>
#include <intrin.h>
#include <conio.h>
using namespace std;
#define s_return(n) if( !s[n] ) return n
#define w_check(n) if( has_zero_byte(w[n]) ) { w += n; break; }
#define w_return(n) if( !(w[0] & (size_t)(0xFF << (8 * n))) ) return (size_t)w - (size_t)s + n
inline size_t has_zero_byte( const size_t n ) // 32bit 전용
{
const size_t finder = (size_t)0x01010101;
const size_t masker = (size_t)0x80808080;
return ( n - finder ) & ( ~n & masker );
}
size_t strlen_ex( const char* s ) // 32bit 전용
{
size_t* w;
s_return( 0 ); s_return( 1 ); s_return( 2 ); s_return( 3 );
w = (size_t*)(((size_t)s & ((size_t)-1 - (sizeof(size_t) - 1))) + sizeof(size_t));
while( 1 )
{
w_check( 0 ); w_check( 1 ); w_check( 2 ); w_check( 3 );
w_check( 4 ); w_check( 5 ); w_check( 6 ); w_check( 7 );
w += sizeof( size_t ) * 2;
}
w_return( 0 ); w_return( 1 ); w_return( 2 ); w_return( 3 );
}
char* strstr_i( const char *src, const char *sub )
{
if ( !((size_t)src | (size_t)sub) ) return NULL;
size_t src_length = strlen_ex(src);
size_t sub_length = strlen_ex(sub);
size_t src_length_word = (src_length + 3) >> 2; // 32bit 전용
size_t src_length_word_1 = src_length_word + 1;
size_t* src_lower_word = new size_t[ src_length_word_1 ];
size_t* src_lower_last = src_lower_word + src_length_word;
char* sub_lower = new char[ sub_length + 1 ];
*src_lower_last = 0;
sub_lower[ sub_length ] = 0;
for( size_t i = 0; i < src_length_word; ++i )
src_lower_word[ i ] = ((size_t*)src)[ i ] | 0x20202020;
for( size_t i = 0; i < sub_length; ++i )
sub_lower[ i ] = sub[ i ] | 0x20;
char* result = strstr( (char*)src_lower_word, sub_lower );
if ( result )
result = (char*)src + ( result - (char*)src_lower_word );
delete[] src_lower_word;
delete[] sub_lower;
return result;
}
int main()
{
char* src = new char[100 * 1024 * 1024];
char sub[] = "Hello world";
for(int i = 0; i < 100 * 1024 * 1024 - 1; ++i ) src[i] = 1;
src[100 * 1024 * 1024 - 1] = 0;
strcpy(src + 100 * 1024 * 1024 - 100, sub);
__int64 begin, elapsed1, elapsed2;
begin = __rdtsc();
size_t position_strstr = ( strstr( src, sub ) - src );
elapsed1 = __rdtsc() - begin;
begin = __rdtsc();
size_t position_strstr_i = ( strstr_i( src, "hello World" ) - src );
elapsed2 = __rdtsc() - begin;
delete[] src;
cout << position_strstr << " " << elapsed1 << endl;
cout << position_strstr_i << " " << elapsed2 << endl;
getchar();
return 0;
}
좀 더 쪼물딱.
ㅋㅋ Windows API 인 StrStrA 는 8배 느린데다 정상동작도 안하네.
퍄
ㅂㅅ이네