String compare performance
Robert Jacques
sandford at jhu.edu
Sun Nov 28 14:12:37 PST 2010
On Sun, 28 Nov 2010 06:44:23 -0500, bearophile <bearophileHUGS at lycos.com>
wrote:
> Robert Jacques:
>
>> I've spent some time having fun this afternoon optimizing array-equals
>> using vectorization techniques. I found that vectorizing using ulongs
>> worked best on my system except with the shortest strings, where a
>> simple
>> Duff's device edged it out. If you'd like to try it out on your data
>> set:
>
> Thank you for your work :-)
> A version with your function, D version #8:
[snip]
> Your function can't be inlined because it's big, so this code isn't
> faster than inlined code like this generated by the compiler:
> (codon.length == 3 && codon[0] == 'T' && codon[1] == 'A' && codon[2] ==
> 'G')
>
> Bye,
> bearophile
Still, part of the point was that string comparisons in general were way
too slow. Anyways, I've applied the same technique in a partially unrolled
version if you want to check it out:
bool arrayComp(T, size_t N)(const T[] a, ref const T[N] b) pure nothrow {
static if(T.sizeof*N <= uint.sizeof) {
return a.length == N && !( (*(cast(uint*)a.ptr) ^
*(cast(uint*)b.ptr)) & (uint.max >> 8*(uint.sizeof - T.sizeof*N) ));
} else static if(T.sizeof*N <= ulong.sizeof) {
return a.length == N && !( (*(cast(ulong*)a.ptr) ^
*(cast(ulong*)b.ptr)) & (ulong.max>> 8*(ulong.sizeof - T.sizeof*N) ));
} else { // Fall back to a loop
if(a.length != N || (*(cast(ulong*)a.ptr) != *(cast(ulong*)b.ptr))
) return false;
enum alignment = T.sizeof*N % ulong.sizeof > 0 ? T.sizeof*N %
ulong.sizeof : ulong.sizeof;
auto pa = cast(ulong*)(cast(ubyte*)a.ptr + alignment);
auto pb = cast(ulong*)(cast(ubyte*)b.ptr + alignment);
auto pa_end = cast(ulong*)(cast(ubyte*)a.ptr + T.sizeof*N);
while (pa < pa_end) {
if(*pa++ != *pb++ ) return false;
}
return true;
}
}
Be warned that you'll have to use strings explicitly typed as immutable
char[N], since both array literals and string literals won't match a this
template.
More information about the Digitalmars-d
mailing list