mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-09-05 17:44:55 -06:00
Core: String::Find optimized in Win32
git-svn-id: svn://ultimatepp.org/upp/trunk@6995 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
9e74bd7802
commit
fabb72f639
3 changed files with 211 additions and 186 deletions
|
|
@ -46,6 +46,7 @@ file
|
|||
heapdbg.cpp optimize_speed,
|
||||
String.h,
|
||||
AString.hpp,
|
||||
StringFind.cpp,
|
||||
String.cpp optimize_speed,
|
||||
WString.cpp optimize_speed,
|
||||
StrUtil.cpp optimize_speed,
|
||||
|
|
|
|||
|
|
@ -2,192 +2,6 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef CPU_X86 // Use unaligned access
|
||||
|
||||
inline
|
||||
bool equal_back_8(const char *a, const char *b, int len)
|
||||
{
|
||||
while(len > 8) {
|
||||
len -= 8;
|
||||
if(Peek64le(a + len) != Peek64le(b + len))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <int step> // Template parameter to be a constant
|
||||
int t_find(const char *ptr, int slen, const char *p, int len, int from)
|
||||
{
|
||||
ASSERT(from >= 0 && from <= slen);
|
||||
int l = slen - len - from;
|
||||
if(l < 0)
|
||||
return -1;
|
||||
const char *s = ptr + from;
|
||||
const char *e = s + l;
|
||||
if(len <= 8) {
|
||||
if(len > 4) {
|
||||
len -= 4;
|
||||
int32 p0 = Peek32le(p);
|
||||
int32 p1 = Peek32le(p + len);
|
||||
while(s <= e) {
|
||||
if(Peek32le(s) == p0 && Peek32le(s + len) == p1)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 4) {
|
||||
int32 p0 = Peek32le(p);
|
||||
while(s <= e) {
|
||||
if(Peek32le(s) == p0)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 3) {
|
||||
int16 p0 = Peek16le(p);
|
||||
char p1 = p[2];
|
||||
while(s <= e) {
|
||||
if(Peek16le(s) == p0 && s[2] == p1)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 2) {
|
||||
int16 p0 = Peek16le(p);
|
||||
while(s <= e) {
|
||||
if(Peek16le(s) == p0)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 1) {
|
||||
char p0 = p[0];
|
||||
while(s <= e) {
|
||||
if(*s == p0)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
int64 p0 = Peek64le(p);
|
||||
if(len <= 16) {
|
||||
len -= 8;
|
||||
int64 p1 = Peek64le(p + len);
|
||||
while(s <= e) {
|
||||
if(Peek64le(s) == p0 && Peek64le(s + len) == p1)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
while(s <= e) {
|
||||
if(Peek64le(s) == p0 && equal_back_8(s, p, len))
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find(const char *text, int len, const char *needle, int nlen, int from)
|
||||
{
|
||||
return t_find<1>(text, len, needle, nlen, from);
|
||||
}
|
||||
|
||||
int find(const wchar *text, int len, const wchar *needle, int nlen, int from)
|
||||
{
|
||||
return t_find<2>((const char *)text, 2 * len, (const char *)needle, 2 * nlen, from) / 2;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class tchar>
|
||||
int t_find(const tchar *ptr, int plen, const tchar *s, int len, int from)
|
||||
{
|
||||
ASSERT(from >= 0 && from <= plen);
|
||||
int l = plen - len - from;
|
||||
if(l < 0)
|
||||
return -1;
|
||||
if(len == 0)
|
||||
return from;
|
||||
const tchar *p = ptr + from;
|
||||
const tchar *e = p + l;
|
||||
if(len > 4) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
tchar sl = s[len - 1];
|
||||
int l_1 = len - 1;
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && sl == p[l_1] && s1 == p[1] && s2 == p[2] &&
|
||||
svo_memeq(s + 3, p + 3, len - 4))
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 4) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
tchar s3 = s[3];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s3 == p[3] && s1 == p[1] && s2 == p[2])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 3) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s2 == p[2] && s1 == p[1])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 2) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s1 == p[1])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tchar s0 = s[0];
|
||||
while(p <= e) {
|
||||
if(s0 == *p)
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find(const char *text, int len, const char *needle, int nlen, int from)
|
||||
{
|
||||
return t_find(text, len, needle, nlen, from);
|
||||
}
|
||||
|
||||
int find(const wchar *text, int len, const wchar *needle, int nlen, int from)
|
||||
{
|
||||
return t_find(text, len, needle, nlen, from);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
void String0::Dsyn()
|
||||
{
|
||||
|
|
|
|||
210
uppsrc/Core/StringFind.cpp
Normal file
210
uppsrc/Core/StringFind.cpp
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
#include "Core.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef CPU_X86 // Use unaligned access
|
||||
|
||||
#ifdef CPU_64
|
||||
inline bool equal_back_8(const char *a, const char *b, int len)
|
||||
{
|
||||
while(len > 8) {
|
||||
len -= 8;
|
||||
if(Peek64le(a + len) != Peek64le(b + len))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
inline bool equal_back_4(const char *a, const char *b, int len)
|
||||
{
|
||||
while(len > 4) {
|
||||
len -= 4;
|
||||
if(Peek32le(a + len) != Peek32le(b + len))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <int step> // Template parameter to be a constant
|
||||
int t_find(const char *ptr, int slen, const char *p, int len, int from)
|
||||
{
|
||||
ASSERT(from >= 0 && from <= slen);
|
||||
int l = slen - len - from;
|
||||
if(l < 0)
|
||||
return -1;
|
||||
const char *s = ptr + from;
|
||||
const char *e = s + l;
|
||||
if(len <= 8) {
|
||||
if(len > 4) {
|
||||
len -= 4;
|
||||
int32 p0 = Peek32le(p);
|
||||
int32 p1 = Peek32le(p + len);
|
||||
while(s <= e) {
|
||||
if(Peek32le(s) == p0 && Peek32le(s + len) == p1)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 4) {
|
||||
int32 p0 = Peek32le(p);
|
||||
while(s <= e) {
|
||||
if(Peek32le(s) == p0)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 3) {
|
||||
int16 p0 = Peek16le(p);
|
||||
char p1 = p[2];
|
||||
while(s <= e) {
|
||||
if(Peek16le(s) == p0 && s[2] == p1)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 2) {
|
||||
int16 p0 = Peek16le(p);
|
||||
while(s <= e) {
|
||||
if(Peek16le(s) == p0)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 1) {
|
||||
char p0 = p[0];
|
||||
while(s <= e) {
|
||||
if(*s == p0)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
#ifdef CPU_64
|
||||
int64 p0 = Peek64le(p);
|
||||
if(len <= 16) {
|
||||
len -= 8;
|
||||
int64 p1 = Peek64le(p + len);
|
||||
while(s <= e) {
|
||||
if(Peek64le(s) == p0 && Peek64le(s + len) == p1)
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
}
|
||||
else
|
||||
while(s <= e) {
|
||||
if(Peek64le(s) == p0 && equal_back_8(s, p, len))
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
#else
|
||||
int32 p0 = Peek32le(p);
|
||||
while(s <= e) {
|
||||
if(Peek32le(s) == p0 && equal_back_4(s, p, len))
|
||||
return (int)(s - ptr);
|
||||
s += step;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find(const char *text, int len, const char *needle, int nlen, int from)
|
||||
{
|
||||
return t_find<1>(text, len, needle, nlen, from);
|
||||
}
|
||||
|
||||
int find(const wchar *text, int len, const wchar *needle, int nlen, int from)
|
||||
{
|
||||
return t_find<2>((const char *)text, 2 * len, (const char *)needle, 2 * nlen, from) / 2;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class tchar>
|
||||
int t_find(const tchar *ptr, int plen, const tchar *s, int len, int from)
|
||||
{
|
||||
ASSERT(from >= 0 && from <= plen);
|
||||
int l = plen - len - from;
|
||||
if(l < 0)
|
||||
return -1;
|
||||
if(len == 0)
|
||||
return from;
|
||||
const tchar *p = ptr + from;
|
||||
const tchar *e = p + l;
|
||||
if(len > 4) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
tchar sl = s[len - 1];
|
||||
int l_1 = len - 1;
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && sl == p[l_1] && s1 == p[1] && s2 == p[2] &&
|
||||
svo_memeq(s + 3, p + 3, len - 4))
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 4) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
tchar s3 = s[3];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s3 == p[3] && s1 == p[1] && s2 == p[2])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 3) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s2 == p[2] && s1 == p[1])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 2) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s1 == p[1])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tchar s0 = s[0];
|
||||
while(p <= e) {
|
||||
if(s0 == *p)
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find(const char *text, int len, const char *needle, int nlen, int from)
|
||||
{
|
||||
return t_find(text, len, needle, nlen, from);
|
||||
}
|
||||
|
||||
int find(const wchar *text, int len, const wchar *needle, int nlen, int from)
|
||||
{
|
||||
return t_find(text, len, needle, nlen, from);
|
||||
}
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
Loading…
Add table
Add a link
Reference in a new issue