I agree that the discussion about the implementation belongs in apr-dev@.
Cross posting my original httpd-dev@ message below yours (the wording
may be httpd -use case- related, sorry about that)...

On Tue, Dec 1, 2015 at 5:31 AM, William A Rowe Jr <wr...@rowe-clan.net> wrote:
> That describes the 'token' use case, right?  While MMX operands let the clib
> devs play with 16-byte/dword/word units, we are principally looking at very
> short strings.  As soon as you do a 16 byte compare w/delimiting the null
> byte, your optimization is lost.
>
> I think we are of one mind on this, sniping aside.  I started with an svn cp
> today from asf subversion, and chose to focus on only the svn_cstring_
> (excluding svn_string and svn_stringbuf ops), but there is room if we give
> the nod and should treat them as 3 seperate groupings.  First commit inbound
> in the morning with lots of room for optimization.


On Nov 30, 2015 11:20, "Yann Ylavic" <ylavic....@gmail.com> wrote:

Sorry for the late, was afk this times...

Regarding the name, I'm fine with ap[r]_cstr[n]casecmp(),
ap[r]_casecmpcstr[n]() or ap[r]_cstr_*() (if we need a set of
functions in this area)..

I think we all agree that the new function(s) would help protocol
"validation" being agnostic wrt the locale, though httpd (as any *nix
program) runs in the "C" locale by default (hence str[n]casecmp()
behave as expected), and this can't be changed unless some
(third-party-)module plays with setlocale(), as Bill said).

So the new function(s) would address two concerns:
1. doing the right thing at the protocol level if/when modules need
custom locales,
2. have an effecient "C"-string caseless comparison function on all
platforms (see tests results below).

For 1. I agree we should not hurry and take the time to review the
kind of changes I proposed in [1].

For 2. I think we can start using the new function(s) whenever we are
dealing with "C"-strings and this is a fast path (eg. Jean-Frederic's
report about ap_proxy_port_of_scheme(), which should be addressed both
in httpd and APR IMHO).


Regarding performances, attached are the tests (and results) I ran on
different systems (linuxes+glibc+gcc only!, i.e.
Debian6+glibc-2.11+gcc-4.4, Debian8+glibc-2.19+gcc-4.9 and
CentOS7+glibc-2.17+gcc-4.8) for the different implementations that
were discussed so far (including standard strncasecmp,
svn_cstring_casecmp, and Mikhail's mi_strcasecmp).

<tl;dr>

a. Our implementation(s) are faster than str[n]casecmp() for strings
lengths < 4 or 8 (depending on sizeof(long), ie. 32bit vs 64bit
system), which matters not only for such short strings but also when
the compared strings differ in these first bytes (our implementation
fails faster too here),

b. Latests str[n]casecmp() (or/and gcc) are far faster (x3) than any
of our proposal in the "C" (or "UTF-8") locale for longer strings, too
bad there is no strcasecmp[_loc]() taking the locale as argument (à la
stdc++)...
*However*, whenever mappings are in place, eg. the famous
mt_MT.ISO-8859, str[n]casecmp() takes the same time as our
implementation (comparing the same number of caseless-equal
characters),

c. Our best implementation, which is performing well in all cases (ie.
no "pathological" behaviour with some cases) is Jim's "ap_casestrcmp"
(the current one).
Actually the ones performing a bit better are those called
"ap_casestrcmp_1" and "ap_casestrcmp_2" in the test, the former being
the same as Jim's but with "++ps1; ++ps2;" done at the end of the
loop, and the latter being my proposed version using an index instead
of char pointers (no gain compared to "ap_casestrcmp_1", not worth the
change...).
So I'd be for using Jim's with the simple "++ps1; ++ps2;" change.

</tl;dr>


The attached test results are the ones run on CentOS7 (because this is
the system of a real/performant machine I can access, and running the
tests on my Debian laptop make it hot enough to be unfair :)
Since I'm not very used to CentOS, I could not make the
"mt_MT.ISO-8859" locale work/being applied, either because I'm doing
things wrong, or sowehow the locale has been updated to avoid this
mapping (though I was able to make it work with latest debians, where
strcasecmp() performs differently depending on the locale...).

So for completeness, I'm pasting the results on a debian jessie for
locales "mt_MT.ISO-8859" and "C" here, since it matters there:

$ LC_ALL=mt_MT.iso88593 ./ap_casecmpstr-O2 'a' 100000000
'CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaAa'
'cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAaa' 0
./ap_casecmpstr-O2 'a' 100000000
"CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaAa"
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAaa" 0: locale "mt_MT.iso88593"
- ap_casecmpstr       : time=06.160937456, res=0
- ap_casecmpstr_1     : time=06.256894742, res=0
- ap_casecmpstr_2     : time=06.136213804, res=0
- ap_casecmpstr_4     : time=06.787756289, res=0
- ap_casecmpstr_3     : time=06.110559311, res=0
- ap_casecmpstr_7     : time=06.844624092, res=0
- ap_casecmpstr_5     : time=06.820174763, res=0
- ap_casecmpstr_6     : time=10.488436936, res=0
- svn_cstring_casecmp : time=07.329213881, res=0
- mi_strcasecmp       : time=10.165367784, res=0
- strcasecmp_ext      : time=06.274211596, res=0
- strcasecmp          : time=06.126361486, res=0
- strcmp              : time=00.590613344, res=-32 != str[n]casecmp()'s result!

$ LC_ALL=mt_MT.iso88593 ./ap_casecmpstr-O2 'a' 100000000
$'\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9'
'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii' 0
./ap_casecmpstr-O2 'a' 100000000 "<...40 unprintable chars here...>"
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" 0: locale "mt_MT.iso88593"
- ap_casecmpstr       : time=00.479203198, res=64 != str[n]casecmp()'s result!
- ap_casecmpstr_1     : time=00.526867671, res=64 != str[n]casecmp()'s result!
- ap_casecmpstr_2     : time=00.525341010, res=64 != str[n]casecmp()'s result!
- ap_casecmpstr_4     : time=00.529071848, res=64 != str[n]casecmp()'s result!
- ap_casecmpstr_3     : time=00.528699442, res=64 != str[n]casecmp()'s result!
- ap_casecmpstr_7     : time=00.507921257, res=64 != str[n]casecmp()'s result!
- ap_casecmpstr_5     : time=00.524753726, res=64 != str[n]casecmp()'s result!
- ap_casecmpstr_6     : time=00.524081999, res=64 != str[n]casecmp()'s result!
- svn_cstring_casecmp : time=00.509402346, res=64 != str[n]casecmp()'s result!
- mi_strcasecmp       : time=00.532081427, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=06.309950716, res=0
- strcasecmp          : time=06.148251655, res=0
- strcmp              : time=00.525644420, res=64 != str[n]casecmp()'s result!

Whereas with "C" locale, I've got:

$ LC_ALL=C ./ap_casecmpstr-O2 'a' 100000000
'CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaAa'
'cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAaa' 0
./ap_casecmpstr-O2 'a' 100000000
"CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaAa"
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAaa" 0: locale "C"
- ap_casecmpstr       : time=06.191792200, res=0
- ap_casecmpstr_1     : time=06.147878566, res=0
- ap_casecmpstr_2     : time=06.333936899, res=0
- ap_casecmpstr_4     : time=06.870865790, res=0
- ap_casecmpstr_3     : time=06.227310131, res=0
- ap_casecmpstr_7     : time=06.856304522, res=0
- ap_casecmpstr_5     : time=06.788184432, res=0
- ap_casecmpstr_6     : time=10.437171106, res=0
- svn_cstring_casecmp : time=07.325735333, res=0
- mi_strcasecmp       : time=10.351743646, res=0
- strcasecmp_ext      : time=01.649636857, res=0
- strcasecmp          : time=01.443062626, res=0
- strcmp              : time=00.502131680, res=-32 != str[n]casecmp()'s result!

$ LC_ALL=C ./ap_casecmpstr-O2 'a' 100000000
$'\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9'
'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii' 0
./ap_casecmpstr-O2 'a' 100000000 "<...40 unprintable chars here...>"
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" 0: locale "C"
- ap_casecmpstr       : time=00.489929313, res=64
- ap_casecmpstr_1     : time=00.537979168, res=64
- ap_casecmpstr_2     : time=00.528165151, res=64
- ap_casecmpstr_4     : time=00.541039123, res=64
- ap_casecmpstr_3     : time=00.545316485, res=64
- ap_casecmpstr_7     : time=00.522669572, res=64
- ap_casecmpstr_5     : time=00.541433772, res=64
- ap_casecmpstr_6     : time=00.529486005, res=64
- svn_cstring_casecmp : time=00.518018373, res=64
- mi_strcasecmp       : time=00.551022179, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=01.070935658, res=64
- strcasecmp          : time=00.950721549, res=64
- strcmp              : time=00.529242598, res=64

Regards,
Yann.

[1] http://permalink.gmane.org/gmane.comp.apache.devel/57670
./ap_casecmpstr-O2 'a' 100000000 "" "" 0: locale "C"
- ap_casecmpstr       : time=00.640384038, res=0
- ap_casecmpstr_1     : time=00.593130506, res=0
- ap_casecmpstr_2     : time=00.597193498, res=0
- ap_casecmpstr_4     : time=00.565044426, res=0
- ap_casecmpstr_3     : time=00.753397231, res=0
- ap_casecmpstr_7     : time=00.603188362, res=0
- ap_casecmpstr_5     : time=00.765887811, res=0
- ap_casecmpstr_6     : time=00.690626986, res=0
- svn_cstring_casecmp : time=00.678165408, res=0
- mi_strcasecmp       : time=00.610619038, res=0
- strcasecmp_ext      : time=01.762789366, res=0
- strcasecmp          : time=01.750946063, res=0
- strcmp              : time=01.318660278, res=0

./ap_casecmpstr-O2 'a' 100000000 "y" "Y" 0: locale "C"
- ap_casecmpstr       : time=00.753437364, res=0
- ap_casecmpstr_1     : time=00.737689713, res=0
- ap_casecmpstr_2     : time=00.735272257, res=0
- ap_casecmpstr_4     : time=00.695582493, res=0
- ap_casecmpstr_3     : time=00.998366448, res=0
- ap_casecmpstr_7     : time=00.738376384, res=0
- ap_casecmpstr_5     : time=00.904844101, res=0
- ap_casecmpstr_6     : time=00.863892825, res=0
- svn_cstring_casecmp : time=00.775427872, res=0
- mi_strcasecmp       : time=00.929957521, res=0
- strcasecmp_ext      : time=01.762589286, res=0
- strcasecmp          : time=01.754966305, res=0
- strcmp              : time=01.320697742, res=32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "Y" "yY" 0: locale "C"
- ap_casecmpstr       : time=00.757572541, res=-1
- ap_casecmpstr_1     : time=00.754116311, res=-1
- ap_casecmpstr_2     : time=00.735113645, res=-1
- ap_casecmpstr_4     : time=00.805432251, res=-1
- ap_casecmpstr_3     : time=01.013017886, res=-1
- ap_casecmpstr_7     : time=00.790319616, res=-1
- ap_casecmpstr_5     : time=00.829388008, res=-1
- ap_casecmpstr_6     : time=00.865841107, res=-1
- svn_cstring_casecmp : time=00.791995746, res=-1
- mi_strcasecmp       : time=00.867140587, res=-1
- strcasecmp_ext      : time=01.762029007, res=-1
- strcasecmp          : time=01.752298368, res=-1
- strcmp              : time=01.325237470, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "yY" "YyY" 0: locale "C"
- ap_casecmpstr       : time=00.943219414, res=-1
- ap_casecmpstr_1     : time=00.942917573, res=-1
- ap_casecmpstr_2     : time=00.923867487, res=-1
- ap_casecmpstr_4     : time=00.920291748, res=-1
- ap_casecmpstr_3     : time=01.130963099, res=-1
- ap_casecmpstr_7     : time=00.918744311, res=-1
- ap_casecmpstr_5     : time=01.018172422, res=-1
- ap_casecmpstr_6     : time=01.138276510, res=-1
- svn_cstring_casecmp : time=00.979354990, res=-1
- mi_strcasecmp       : time=01.092368345, res=-1
- strcasecmp_ext      : time=01.760000072, res=-1
- strcasecmp          : time=01.750010541, res=-1
- strcmp              : time=01.318228149, res=32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "©" "i" 0: locale "C"
- ap_casecmpstr       : time=00.419729508, res=64
- ap_casecmpstr_1     : time=00.417554486, res=64
- ap_casecmpstr_2     : time=00.422133322, res=64
- ap_casecmpstr_4     : time=00.451919210, res=64
- ap_casecmpstr_3     : time=00.527282630, res=64
- ap_casecmpstr_7     : time=00.451920962, res=64
- ap_casecmpstr_5     : time=00.451981525, res=64
- ap_casecmpstr_6     : time=00.490222955, res=64
- svn_cstring_casecmp : time=00.414273599, res=64
- mi_strcasecmp       : time=00.489530114, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=01.760054623, res=64
- strcasecmp          : time=01.747246160, res=64
- strcmp              : time=01.318076265, res=64

./ap_casecmpstr-O2 'a' 100000000 "cycoOaA" "cycoOaA" 0: locale "C"
- ap_casecmpstr       : time=01.694630305, res=0
- ap_casecmpstr_1     : time=01.659402164, res=0
- ap_casecmpstr_2     : time=01.710523613, res=0
- ap_casecmpstr_4     : time=01.623102504, res=0
- ap_casecmpstr_3     : time=02.344348536, res=0
- ap_casecmpstr_7     : time=01.848482492, res=0
- ap_casecmpstr_5     : time=02.451482558, res=0
- ap_casecmpstr_6     : time=02.149579454, res=0
- svn_cstring_casecmp : time=01.891067360, res=0
- mi_strcasecmp       : time=02.300626815, res=0
- strcasecmp_ext      : time=01.762774725, res=0
- strcasecmp          : time=01.752902687, res=0
- strcmp              : time=01.320002845, res=0

./ap_casecmpstr-O2 'a' 100000000 "cycycoOoOaAaA" "cycycoOoOaAaA" 0: locale "C"
- ap_casecmpstr       : time=02.563830260, res=0
- ap_casecmpstr_1     : time=02.585250639, res=0
- ap_casecmpstr_2     : time=02.677421819, res=0
- ap_casecmpstr_4     : time=02.539338728, res=0
- ap_casecmpstr_3     : time=03.696615294, res=0
- ap_casecmpstr_7     : time=02.753217299, res=0
- ap_casecmpstr_5     : time=03.808876167, res=0
- ap_casecmpstr_6     : time=03.280841543, res=0
- svn_cstring_casecmp : time=03.049183608, res=0
- mi_strcasecmp       : time=03.676306392, res=0
- strcasecmp_ext      : time=01.767568075, res=0
- strcasecmp          : time=01.748285731, res=0
- strcmp              : time=01.319547187, res=0

./ap_casecmpstr-O2 'a' 100000000 "€�‚ƒ„üýþÿ" "€�‚ƒ„üýþÿ" 0: locale "C"
- ap_casecmpstr       : time=01.994451268, res=0
- ap_casecmpstr_1     : time=01.958683722, res=0
- ap_casecmpstr_2     : time=01.996443920, res=0
- ap_casecmpstr_4     : time=01.964194500, res=0
- ap_casecmpstr_3     : time=02.787465195, res=0
- ap_casecmpstr_7     : time=02.167400371, res=0
- ap_casecmpstr_5     : time=02.903496993, res=0
- ap_casecmpstr_6     : time=02.523538695, res=0
- svn_cstring_casecmp : time=02.260331726, res=0
- mi_strcasecmp       : time=02.749741057, res=0
- strcasecmp_ext      : time=01.748763286, res=0
- strcasecmp          : time=01.744303906, res=0
- strcmp              : time=01.318391059, res=0

./ap_casecmpstr-O2 'a' 100000000 "cycycycycycycycycycoOoOoOoOoOaAaAaAaAaAa" 
"cycycycycycycycycycoOoOoOoOoOaAaAaAaAaAa" 0: locale "C"
- ap_casecmpstr       : time=06.669256560, res=0
- ap_casecmpstr_1     : time=06.639707322, res=0
- ap_casecmpstr_2     : time=06.636884956, res=0
- ap_casecmpstr_4     : time=06.594694556, res=0
- ap_casecmpstr_3     : time=09.797156337, res=0
- ap_casecmpstr_7     : time=06.819170498, res=0
- ap_casecmpstr_5     : time=09.909330381, res=0
- ap_casecmpstr_6     : time=08.371682408, res=0
- svn_cstring_casecmp : time=08.157783193, res=0
- mi_strcasecmp       : time=09.832437801, res=0
- strcasecmp_ext      : time=01.583949115, res=0
- strcasecmp          : time=01.560225304, res=0
- strcmp              : time=01.001964370, res=0

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCooooooooooaaaaaaaaaaa" 
"CyCyCyCyCyCyCyCyCyCooooooooooaaaaaaaaaaa" 0: locale "C"
- ap_casecmpstr       : time=06.650305371, res=0
- ap_casecmpstr_1     : time=06.654576481, res=0
- ap_casecmpstr_2     : time=06.649280152, res=0
- ap_casecmpstr_4     : time=06.624720864, res=0
- ap_casecmpstr_3     : time=09.813916614, res=0
- ap_casecmpstr_7     : time=06.820279813, res=0
- ap_casecmpstr_5     : time=09.919433430, res=0
- ap_casecmpstr_6     : time=08.387737251, res=0
- svn_cstring_casecmp : time=08.106081607, res=0
- mi_strcasecmp       : time=09.806882688, res=0
- strcasecmp_ext      : time=01.582266659, res=0
- strcasecmp          : time=01.556152949, res=0
- strcmp              : time=00.998834168, res=0

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaAa" 
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAaa" 0: locale "C"
- ap_casecmpstr       : time=06.655348499, res=0
- ap_casecmpstr_1     : time=06.638661516, res=0
- ap_casecmpstr_2     : time=06.637039976, res=0
- ap_casecmpstr_4     : time=07.563006272, res=0
- ap_casecmpstr_3     : time=11.818180888, res=0
- ap_casecmpstr_7     : time=07.750561264, res=0
- ap_casecmpstr_5     : time=07.870441830, res=0
- ap_casecmpstr_6     : time=12.677967302, res=0
- svn_cstring_casecmp : time=08.175433923, res=0
- mi_strcasecmp       : time=12.286791001, res=0
- strcasecmp_ext      : time=01.583389727, res=0
- strcasecmp          : time=01.559375146, res=0
- strcmp              : time=00.491665174, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaA[" 
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAa]" 0: locale "C"
- ap_casecmpstr       : time=06.335980019, res=-2
- ap_casecmpstr_1     : time=06.331726342, res=-2
- ap_casecmpstr_2     : time=06.335989021, res=-2
- ap_casecmpstr_4     : time=06.335414351, res=-2
- ap_casecmpstr_3     : time=07.775223460, res=-2
- ap_casecmpstr_7     : time=06.336236219, res=-2
- ap_casecmpstr_5     : time=06.354284743, res=-2
- ap_casecmpstr_6     : time=11.242045966, res=-2
- svn_cstring_casecmp : time=07.746695069, res=-2
- mi_strcasecmp       : time=10.196571734, res=-2
- strcasecmp_ext      : time=01.682655460, res=-2
- strcasecmp          : time=01.638339099, res=-2
- strcmp              : time=00.490800588, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©" 
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" 0: locale "C"
- ap_casecmpstr       : time=00.414413641, res=64
- ap_casecmpstr_1     : time=00.414534407, res=64
- ap_casecmpstr_2     : time=00.414317281, res=64
- ap_casecmpstr_4     : time=00.452096450, res=64
- ap_casecmpstr_3     : time=00.527448981, res=64
- ap_casecmpstr_7     : time=00.452020092, res=64
- ap_casecmpstr_5     : time=00.452099224, res=64
- ap_casecmpstr_6     : time=00.489783046, res=64
- svn_cstring_casecmp : time=00.414846528, res=64
- mi_strcasecmp       : time=00.452035856, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=00.860608796, res=64
- strcasecmp          : time=00.831151117, res=64
- strcmp              : time=00.490393447, res=64

./ap_casecmpstr-O2 'a' 100000000 "©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i" 
"i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©" 0: locale "C"
- ap_casecmpstr       : time=00.414577373, res=64
- ap_casecmpstr_1     : time=00.414867604, res=64
- ap_casecmpstr_2     : time=00.415004875, res=64
- ap_casecmpstr_4     : time=00.452847362, res=64
- ap_casecmpstr_3     : time=00.528309811, res=64
- ap_casecmpstr_7     : time=00.452314851, res=64
- ap_casecmpstr_5     : time=00.452469318, res=64
- ap_casecmpstr_6     : time=00.490152391, res=64
- svn_cstring_casecmp : time=00.414680868, res=64
- mi_strcasecmp       : time=00.452586598, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=00.861922685, res=64
- strcasecmp          : time=00.831992190, res=64
- strcmp              : time=00.490907202, res=64

./ap_casecmpstr-O2 'a' 100000000 "" "" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=00.641145567, res=0
- ap_casecmpstr_1     : time=00.609888358, res=0
- ap_casecmpstr_2     : time=00.601538879, res=0
- ap_casecmpstr_4     : time=00.565699477, res=0
- ap_casecmpstr_3     : time=00.754492646, res=0
- ap_casecmpstr_7     : time=00.603326130, res=0
- ap_casecmpstr_5     : time=00.766869385, res=0
- ap_casecmpstr_6     : time=00.691249771, res=0
- svn_cstring_casecmp : time=00.680531538, res=0
- mi_strcasecmp       : time=00.602795466, res=0
- strcasecmp_ext      : time=01.764745966, res=0
- strcasecmp          : time=01.753407513, res=0
- strcmp              : time=01.320041747, res=0

./ap_casecmpstr-O2 'a' 100000000 "y" "Y" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=01.282221347, res=0
- ap_casecmpstr_1     : time=01.244245422, res=0
- ap_casecmpstr_2     : time=00.996139951, res=0
- ap_casecmpstr_4     : time=01.131309388, res=0
- ap_casecmpstr_3     : time=01.320144624, res=0
- ap_casecmpstr_7     : time=00.930367862, res=0
- ap_casecmpstr_5     : time=00.943680696, res=0
- ap_casecmpstr_6     : time=01.218793523, res=0
- svn_cstring_casecmp : time=01.083248729, res=0
- mi_strcasecmp       : time=01.247826174, res=0
- strcasecmp_ext      : time=01.796668859, res=0
- strcasecmp          : time=01.889487910, res=0
- strcmp              : time=01.542656852, res=32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "Y" "yY" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=00.757203098, res=-1
- ap_casecmpstr_1     : time=00.754419737, res=-1
- ap_casecmpstr_2     : time=00.726706434, res=-1
- ap_casecmpstr_4     : time=00.811898140, res=-1
- ap_casecmpstr_3     : time=01.012690919, res=-1
- ap_casecmpstr_7     : time=00.766647990, res=-1
- ap_casecmpstr_5     : time=00.829594545, res=-1
- ap_casecmpstr_6     : time=00.867465773, res=-1
- svn_cstring_casecmp : time=00.798370265, res=-1
- mi_strcasecmp       : time=00.897649910, res=-1
- strcasecmp_ext      : time=01.761816167, res=-1
- strcasecmp          : time=01.753532293, res=-1
- strcmp              : time=01.319561000, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "yY" "YyY" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=00.953095572, res=-1
- ap_casecmpstr_1     : time=00.943206017, res=-1
- ap_casecmpstr_2     : time=00.923962071, res=-1
- ap_casecmpstr_4     : time=00.928634433, res=-1
- ap_casecmpstr_3     : time=01.134056719, res=-1
- ap_casecmpstr_7     : time=00.907492286, res=-1
- ap_casecmpstr_5     : time=00.980528677, res=-1
- ap_casecmpstr_6     : time=01.139032245, res=-1
- svn_cstring_casecmp : time=00.980800234, res=-1
- mi_strcasecmp       : time=01.094000332, res=-1
- strcasecmp_ext      : time=01.762008167, res=-1
- strcasecmp          : time=01.753543561, res=-1
- strcmp              : time=01.319834965, res=32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "©" "i" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=00.426840669, res=64
- ap_casecmpstr_1     : time=00.427935057, res=64
- ap_casecmpstr_2     : time=00.424302912, res=64
- ap_casecmpstr_4     : time=00.452532925, res=64
- ap_casecmpstr_3     : time=00.531995293, res=64
- ap_casecmpstr_7     : time=00.452958313, res=64
- ap_casecmpstr_5     : time=00.452615862, res=64
- ap_casecmpstr_6     : time=00.490712926, res=64
- svn_cstring_casecmp : time=00.415048134, res=64
- mi_strcasecmp       : time=00.492307996, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=01.762381848, res=64
- strcasecmp          : time=01.752629704, res=64
- strcmp              : time=01.319119418, res=64

./ap_casecmpstr-O2 'a' 100000000 "cycoOaA" "cycoOaA" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=01.657913777, res=0
- ap_casecmpstr_1     : time=01.658264820, res=0
- ap_casecmpstr_2     : time=01.722081478, res=0
- ap_casecmpstr_4     : time=01.621587546, res=0
- ap_casecmpstr_3     : time=02.336116840, res=0
- ap_casecmpstr_7     : time=01.846673294, res=0
- ap_casecmpstr_5     : time=02.449368991, res=0
- ap_casecmpstr_6     : time=02.148430673, res=0
- svn_cstring_casecmp : time=01.889283350, res=0
- mi_strcasecmp       : time=02.300379339, res=0
- strcasecmp_ext      : time=01.762746624, res=0
- strcasecmp          : time=01.754282133, res=0
- strcmp              : time=01.320408109, res=0

./ap_casecmpstr-O2 'a' 100000000 "cycycoOoOaAaA" "cycycoOoOaAaA" 0: locale 
"en_US.utf8"
- ap_casecmpstr       : time=02.564406575, res=0
- ap_casecmpstr_1     : time=02.585779993, res=0
- ap_casecmpstr_2     : time=02.601554883, res=0
- ap_casecmpstr_4     : time=02.526332826, res=0
- ap_casecmpstr_3     : time=03.693620447, res=0
- ap_casecmpstr_7     : time=02.750727898, res=0
- ap_casecmpstr_5     : time=03.815759385, res=0
- ap_casecmpstr_6     : time=03.278410089, res=0
- svn_cstring_casecmp : time=03.014331469, res=0
- mi_strcasecmp       : time=03.682960588, res=0
- strcasecmp_ext      : time=01.761896886, res=0
- strcasecmp          : time=01.751093270, res=0
- strcmp              : time=01.318640909, res=0

./ap_casecmpstr-O2 'a' 100000000 "€�‚ƒ„üýþÿ" "€�‚ƒ„üýþÿ" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=01.960050082, res=0
- ap_casecmpstr_1     : time=01.959541453, res=0
- ap_casecmpstr_2     : time=01.997253969, res=0
- ap_casecmpstr_4     : time=01.975236188, res=0
- ap_casecmpstr_3     : time=02.788369968, res=0
- ap_casecmpstr_7     : time=02.176410488, res=0
- ap_casecmpstr_5     : time=02.925170489, res=0
- ap_casecmpstr_6     : time=02.527578138, res=0
- svn_cstring_casecmp : time=02.283964332, res=0
- mi_strcasecmp       : time=02.752385250, res=0
- strcasecmp_ext      : time=01.767191061, res=0
- strcasecmp          : time=01.754398766, res=0
- strcmp              : time=01.319738617, res=0

./ap_casecmpstr-O2 'a' 100000000 "cycycycycycycycycycoOoOoOoOoOaAaAaAaAaAa" 
"cycycycycycycycycycoOoOoOoOoOaAaAaAaAaAa" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=06.635915171, res=0
- ap_casecmpstr_1     : time=06.678780865, res=0
- ap_casecmpstr_2     : time=06.636321870, res=0
- ap_casecmpstr_4     : time=06.594981355, res=0
- ap_casecmpstr_3     : time=09.820577758, res=0
- ap_casecmpstr_7     : time=06.832226458, res=0
- ap_casecmpstr_5     : time=09.928551672, res=0
- ap_casecmpstr_6     : time=08.388523113, res=0
- svn_cstring_casecmp : time=08.100989337, res=0
- mi_strcasecmp       : time=09.824529881, res=0
- strcasecmp_ext      : time=02.110070299, res=0
- strcasecmp          : time=01.808404026, res=0
- strcmp              : time=01.111373554, res=0

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCooooooooooaaaaaaaaaaa" 
"CyCyCyCyCyCyCyCyCyCooooooooooaaaaaaaaaaa" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=06.651205713, res=0
- ap_casecmpstr_1     : time=06.629108960, res=0
- ap_casecmpstr_2     : time=06.629783982, res=0
- ap_casecmpstr_4     : time=06.591745538, res=0
- ap_casecmpstr_3     : time=09.793296741, res=0
- ap_casecmpstr_7     : time=06.817228993, res=0
- ap_casecmpstr_5     : time=09.494798815, res=0
- ap_casecmpstr_6     : time=08.361268077, res=0
- svn_cstring_casecmp : time=08.098537465, res=0
- mi_strcasecmp       : time=09.791542417, res=0
- strcasecmp_ext      : time=01.597872071, res=0
- strcasecmp          : time=01.555175036, res=0
- strcmp              : time=01.111237644, res=0

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaAa" 
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAaa" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=06.649448530, res=0
- ap_casecmpstr_1     : time=06.629232685, res=0
- ap_casecmpstr_2     : time=06.629103560, res=0
- ap_casecmpstr_4     : time=07.556613602, res=0
- ap_casecmpstr_3     : time=11.713992669, res=0
- ap_casecmpstr_7     : time=07.740640315, res=0
- ap_casecmpstr_5     : time=07.833838752, res=0
- ap_casecmpstr_6     : time=12.655254405, res=0
- svn_cstring_casecmp : time=08.098352032, res=0
- mi_strcasecmp       : time=12.240203602, res=0
- strcasecmp_ext      : time=01.598518980, res=0
- strcasecmp          : time=01.557609939, res=0
- strcmp              : time=00.887063214, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaA[" 
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAa]" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=06.327538981, res=-2
- ap_casecmpstr_1     : time=06.328665779, res=-2
- ap_casecmpstr_2     : time=06.327949880, res=-2
- ap_casecmpstr_4     : time=06.327368204, res=-2
- ap_casecmpstr_3     : time=07.759602949, res=-2
- ap_casecmpstr_7     : time=06.327998797, res=-2
- ap_casecmpstr_5     : time=06.327519168, res=-2
- ap_casecmpstr_6     : time=11.178894186, res=-2
- svn_cstring_casecmp : time=07.720933363, res=-2
- mi_strcasecmp       : time=10.222892445, res=-2
- strcasecmp_ext      : time=01.900486341, res=-2
- strcasecmp          : time=01.636543040, res=-2
- strcmp              : time=01.017094723, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©" 
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=00.414390873, res=64
- ap_casecmpstr_1     : time=00.414258308, res=64
- ap_casecmpstr_2     : time=00.414427017, res=64
- ap_casecmpstr_4     : time=00.452101598, res=64
- ap_casecmpstr_3     : time=00.527296614, res=64
- ap_casecmpstr_7     : time=00.452058112, res=64
- ap_casecmpstr_5     : time=00.451889722, res=64
- ap_casecmpstr_6     : time=00.489586725, res=64
- svn_cstring_casecmp : time=00.414446032, res=64
- mi_strcasecmp       : time=00.451907243, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=00.870470328, res=64
- strcasecmp          : time=00.830393960, res=64
- strcmp              : time=00.890181255, res=64

./ap_casecmpstr-O2 'a' 100000000 "©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i" 
"i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©" 0: locale "en_US.utf8"
- ap_casecmpstr       : time=00.414317548, res=64
- ap_casecmpstr_1     : time=00.414289720, res=64
- ap_casecmpstr_2     : time=00.414308253, res=64
- ap_casecmpstr_4     : time=00.451896676, res=64
- ap_casecmpstr_3     : time=00.527289519, res=64
- ap_casecmpstr_7     : time=00.452154279, res=64
- ap_casecmpstr_5     : time=00.452067113, res=64
- ap_casecmpstr_6     : time=00.489635747, res=64
- svn_cstring_casecmp : time=00.414279436, res=64
- mi_strcasecmp       : time=00.452010350, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=00.868338098, res=64
- strcasecmp          : time=00.830392779, res=64
- strcmp              : time=00.887800359, res=64

./ap_casecmpstr-O2 'a' 100000000 "" "" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=00.640371043, res=0
- ap_casecmpstr_1     : time=00.594717724, res=0
- ap_casecmpstr_2     : time=00.584599464, res=0
- ap_casecmpstr_4     : time=00.564915493, res=0
- ap_casecmpstr_3     : time=00.753144246, res=0
- ap_casecmpstr_7     : time=00.602551390, res=0
- ap_casecmpstr_5     : time=00.766060377, res=0
- ap_casecmpstr_6     : time=00.690556273, res=0
- svn_cstring_casecmp : time=00.677934823, res=0
- mi_strcasecmp       : time=00.602122937, res=0
- strcasecmp_ext      : time=01.760175908, res=0
- strcasecmp          : time=01.752752488, res=0
- strcmp              : time=01.318195781, res=0

./ap_casecmpstr-O2 'a' 100000000 "y" "Y" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=00.792508651, res=0
- ap_casecmpstr_1     : time=00.746417014, res=0
- ap_casecmpstr_2     : time=00.735894241, res=0
- ap_casecmpstr_4     : time=00.716361203, res=0
- ap_casecmpstr_3     : time=00.991827100, res=0
- ap_casecmpstr_7     : time=00.780238583, res=0
- ap_casecmpstr_5     : time=00.905144784, res=0
- ap_casecmpstr_6     : time=00.863715349, res=0
- svn_cstring_casecmp : time=00.772657058, res=0
- mi_strcasecmp       : time=00.928106372, res=0
- strcasecmp_ext      : time=01.761050340, res=0
- strcasecmp          : time=01.755542776, res=0
- strcmp              : time=01.318427925, res=32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "Y" "yY" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=00.756461680, res=-1
- ap_casecmpstr_1     : time=00.753833665, res=-1
- ap_casecmpstr_2     : time=00.725986419, res=-1
- ap_casecmpstr_4     : time=00.793476806, res=-1
- ap_casecmpstr_3     : time=01.011481038, res=-1
- ap_casecmpstr_7     : time=00.828950777, res=-1
- ap_casecmpstr_5     : time=00.828722019, res=-1
- ap_casecmpstr_6     : time=00.866116507, res=-1
- svn_cstring_casecmp : time=00.793347450, res=-1
- mi_strcasecmp       : time=00.870566455, res=-1
- strcasecmp_ext      : time=01.760597646, res=-1
- strcasecmp          : time=01.752242892, res=-1
- strcmp              : time=01.319414495, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "yY" "YyY" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=00.941756070, res=-1
- ap_casecmpstr_1     : time=00.942026628, res=-1
- ap_casecmpstr_2     : time=00.922519051, res=-1
- ap_casecmpstr_4     : time=00.915336679, res=-1
- ap_casecmpstr_3     : time=01.143547946, res=-1
- ap_casecmpstr_7     : time=00.915128775, res=-1
- ap_casecmpstr_5     : time=00.979400202, res=-1
- ap_casecmpstr_6     : time=01.138378746, res=-1
- svn_cstring_casecmp : time=00.979474620, res=-1
- mi_strcasecmp       : time=01.092644925, res=-1
- strcasecmp_ext      : time=01.764247232, res=-1
- strcasecmp          : time=01.751496683, res=-1
- strcmp              : time=01.318789180, res=32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "©" "i" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=00.428823599, res=64
- ap_casecmpstr_1     : time=00.428208348, res=64
- ap_casecmpstr_2     : time=00.424450460, res=64
- ap_casecmpstr_4     : time=00.451970786, res=64
- ap_casecmpstr_3     : time=00.527441654, res=64
- ap_casecmpstr_7     : time=00.451989160, res=64
- ap_casecmpstr_5     : time=00.452127128, res=64
- ap_casecmpstr_6     : time=00.492328375, res=64
- svn_cstring_casecmp : time=00.414492665, res=64
- mi_strcasecmp       : time=00.490132530, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=01.766176139, res=64
- strcasecmp          : time=01.754969154, res=64
- strcmp              : time=01.319354415, res=64

./ap_casecmpstr-O2 'a' 100000000 "cycoOaA" "cycoOaA" 0: locale 
"mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=01.657633307, res=0
- ap_casecmpstr_1     : time=01.658062098, res=0
- ap_casecmpstr_2     : time=01.732953557, res=0
- ap_casecmpstr_4     : time=01.620238199, res=0
- ap_casecmpstr_3     : time=02.336275300, res=0
- ap_casecmpstr_7     : time=01.847140603, res=0
- ap_casecmpstr_5     : time=02.449100313, res=0
- ap_casecmpstr_6     : time=02.147906010, res=0
- svn_cstring_casecmp : time=01.888169699, res=0
- mi_strcasecmp       : time=02.299418996, res=0
- strcasecmp_ext      : time=01.761782567, res=0
- strcasecmp          : time=01.754144172, res=0
- strcmp              : time=01.319587154, res=0

./ap_casecmpstr-O2 'a' 100000000 "cycycoOoOaAaA" "cycycoOoOaAaA" 0: locale 
"mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=02.603859662, res=0
- ap_casecmpstr_1     : time=02.563746751, res=0
- ap_casecmpstr_2     : time=02.614852689, res=0
- ap_casecmpstr_4     : time=02.526608937, res=0
- ap_casecmpstr_3     : time=03.710698803, res=0
- ap_casecmpstr_7     : time=02.753013678, res=0
- ap_casecmpstr_5     : time=03.808240226, res=0
- ap_casecmpstr_6     : time=03.289607528, res=0
- svn_cstring_casecmp : time=03.016375836, res=0
- mi_strcasecmp       : time=03.658259577, res=0
- strcasecmp_ext      : time=01.766159508, res=0
- strcasecmp          : time=01.757015670, res=0
- strcmp              : time=01.319848799, res=0

./ap_casecmpstr-O2 'a' 100000000 "€�‚ƒ„üýþÿ" "€�‚ƒ„üýþÿ" 0: locale 
"mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=01.960545096, res=0
- ap_casecmpstr_1     : time=01.960928758, res=0
- ap_casecmpstr_2     : time=02.013614851, res=0
- ap_casecmpstr_4     : time=02.013748946, res=0
- ap_casecmpstr_3     : time=02.789989023, res=0
- ap_casecmpstr_7     : time=02.163668652, res=0
- ap_casecmpstr_5     : time=02.901261450, res=0
- ap_casecmpstr_6     : time=02.524040885, res=0
- svn_cstring_casecmp : time=02.261919777, res=0
- mi_strcasecmp       : time=02.759172124, res=0
- strcasecmp_ext      : time=01.762233413, res=0
- strcasecmp          : time=01.757870881, res=0
- strcmp              : time=01.319805676, res=0

./ap_casecmpstr-O2 'a' 100000000 "cycycycycycycycycycoOoOoOoOoOaAaAaAaAaAa" 
"cycycycycycycycycycoOoOoOoOoOaAaAaAaAaAa" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=06.652001061, res=0
- ap_casecmpstr_1     : time=06.702640201, res=0
- ap_casecmpstr_2     : time=06.636991475, res=0
- ap_casecmpstr_4     : time=06.595785765, res=0
- ap_casecmpstr_3     : time=09.799577119, res=0
- ap_casecmpstr_7     : time=06.836962472, res=0
- ap_casecmpstr_5     : time=09.937424964, res=0
- ap_casecmpstr_6     : time=08.369975735, res=0
- svn_cstring_casecmp : time=08.141865032, res=0
- mi_strcasecmp       : time=09.815155351, res=0
- strcasecmp_ext      : time=01.599383035, res=0
- strcasecmp          : time=01.556327837, res=0
- strcmp              : time=01.112489568, res=0

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCooooooooooaaaaaaaaaaa" 
"CyCyCyCyCyCyCyCyCyCooooooooooaaaaaaaaaaa" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=06.664437118, res=0
- ap_casecmpstr_1     : time=06.663934368, res=0
- ap_casecmpstr_2     : time=06.638477537, res=0
- ap_casecmpstr_4     : time=06.604573197, res=0
- ap_casecmpstr_3     : time=09.796764175, res=0
- ap_casecmpstr_7     : time=06.828152653, res=0
- ap_casecmpstr_5     : time=09.922564209, res=0
- ap_casecmpstr_6     : time=08.365246634, res=0
- svn_cstring_casecmp : time=08.143237782, res=0
- mi_strcasecmp       : time=09.796775122, res=0
- strcasecmp_ext      : time=01.843233764, res=0
- strcasecmp          : time=01.771159699, res=0
- strcmp              : time=01.111301819, res=0

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaAa" 
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAaa" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=06.644365690, res=0
- ap_casecmpstr_1     : time=06.631499790, res=0
- ap_casecmpstr_2     : time=06.635229515, res=0
- ap_casecmpstr_4     : time=07.515619122, res=0
- ap_casecmpstr_3     : time=11.788702525, res=0
- ap_casecmpstr_7     : time=07.774585657, res=0
- ap_casecmpstr_5     : time=07.836149469, res=0
- ap_casecmpstr_6     : time=12.660483863, res=0
- svn_cstring_casecmp : time=08.100219687, res=0
- mi_strcasecmp       : time=12.289171678, res=0
- strcasecmp_ext      : time=01.600405816, res=0
- strcasecmp          : time=01.559409089, res=0
- strcmp              : time=00.888402146, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "CyCyCyCyCyCyCyCyCyCoOoOoOoOoOaAaAaAaAaA[" 
"cYcYcYcYcYcYcYcYcYcOoOoOoOoOoAaAaAaAaAa]" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=06.367300711, res=-2
- ap_casecmpstr_1     : time=06.329501237, res=-2
- ap_casecmpstr_2     : time=06.327803558, res=-2
- ap_casecmpstr_4     : time=06.328360767, res=-2
- ap_casecmpstr_3     : time=07.760318552, res=-2
- ap_casecmpstr_7     : time=06.329602060, res=-2
- ap_casecmpstr_5     : time=06.328569697, res=-2
- ap_casecmpstr_6     : time=11.180830923, res=-2
- svn_cstring_casecmp : time=07.723762684, res=-2
- mi_strcasecmp       : time=10.184163517, res=-2
- strcasecmp_ext      : time=01.684902845, res=-2
- strcasecmp          : time=01.636064976, res=-2
- strcmp              : time=00.887912003, res=-32 != str[n]casecmp()'s result!

./ap_casecmpstr-O2 'a' 100000000 "©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©" 
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=00.449202908, res=64
- ap_casecmpstr_1     : time=00.414421291, res=64
- ap_casecmpstr_2     : time=00.414319359, res=64
- ap_casecmpstr_4     : time=00.452124239, res=64
- ap_casecmpstr_3     : time=00.527267878, res=64
- ap_casecmpstr_7     : time=00.451985356, res=64
- ap_casecmpstr_5     : time=00.451940441, res=64
- ap_casecmpstr_6     : time=00.489645932, res=64
- svn_cstring_casecmp : time=00.414380819, res=64
- mi_strcasecmp       : time=00.452201381, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=01.092335730, res=64
- strcasecmp          : time=01.054526846, res=64
- strcmp              : time=00.887389377, res=64

./ap_casecmpstr-O2 'a' 100000000 "©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i" 
"i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©i©" 0: locale "mt_MT.ISO-8859-3"
- ap_casecmpstr       : time=00.414481440, res=64
- ap_casecmpstr_1     : time=00.414303079, res=64
- ap_casecmpstr_2     : time=00.414388106, res=64
- ap_casecmpstr_4     : time=00.452031610, res=64
- ap_casecmpstr_3     : time=00.527296694, res=64
- ap_casecmpstr_7     : time=00.451972569, res=64
- ap_casecmpstr_5     : time=00.452012470, res=64
- ap_casecmpstr_6     : time=00.489645409, res=64
- svn_cstring_casecmp : time=00.414339000, res=64
- mi_strcasecmp       : time=00.452158280, res=96 != str[n]casecmp()'s result!
- strcasecmp_ext      : time=00.868847302, res=64
- strcasecmp          : time=00.830495092, res=64
- strcmp              : time=00.893023897, res=64

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
#include <time.h>
#include <locale.h>
#include <assert.h>

extern int ap_casecmpstr(const char *s1, const char *s2);
extern int ap_casecmpstrn(const char *s1, const char *s2, size_t n);

extern int ap_casecmpstr_1(const char *s1, const char *s2);
extern int ap_casecmpstrn_1(const char *s1, const char *s2, size_t n);

extern int ap_casecmpstr_2(const char *s1, const char *s2);
extern int ap_casecmpstrn_2(const char *s1, const char *s2, size_t n);

extern int ap_casecmpstr_3(const char *s1, const char *s2);
extern int ap_casecmpstrn_3(const char *s1, const char *s2, size_t n);

extern int ap_casecmpstr_4(const char *s1, const char *s2);
extern int ap_casecmpstrn_4(const char *s1, const char *s2, size_t n);

extern int ap_casecmpstr_5(const char *s1, const char *s2);
extern int ap_casecmpstrn_5(const char *s1, const char *s2, size_t n);

extern int ap_casecmpstr_6(const char *s1, const char *s2);
extern int ap_casecmpstrn_6(const char *s1, const char *s2, size_t n);

extern int ap_casecmpstr_7(const char *s1, const char *s2);
extern int ap_casecmpstrn_7(const char *s1, const char *s2, size_t n);

extern int mi_strcasecmp(const char *s1, const char *s2);
extern int mi_strncasecmp(const char *s1, const char *s2, size_t n);

extern int strcasecmp_ext(const char *s1, const char *s2);
extern int strncasecmp_ext(const char *s1, const char *s2, size_t n);

extern int svn_cstring_casecmp(const char *str1, const char *str2);
extern int svn_cstring_ncasecmp(const char *str1, const char *str2, size_t n);


#define PROG argv[0]
#define METHOD argv[1]
#define NB atoi(argv[2])
#define S1 argv[3]
#define S2 argv[4]
#define LEN atoi(argv[5])

/* The ++ are here to try to prevent some optimization done by gcc */
#define FOR for (i=0; i<nb; i++, (S1[burn])+=2, (S2[burn])+=2)

#define RUN(m, mn, id) \
do { \
    if (*METHOD == 'a' || strchr(METHOD, id)) { \
        int res = 0; \
        int i, nb = NB, len = LEN; \
        struct timespec tvs, tve; \
        int64_t diff; \
        size_t burn; \
        int match; \
        \
        burn = strlen(S1) < strlen(S2) ? strlen(S1) : strlen(S2); \
        assert(burn > 0); \
        burn--; \
        S1[burn] = 1; \
        S2[burn] = 1; \
        \
        printf("- %-20s: ", len == 0 ? #m : #mn); \
        fflush(stdout); \
        \
        if (len == 0) { \
            match = (m(S1, S2) == strcasecmp(S1, S2)); \
        } \
        else { \
            match = (mn(S1, S2, len) != strncasecmp(S1, S2, len)); \
        } \
        \
        clock_gettime(CLOCK_MONOTONIC, &tvs); \
        if (len == 0) { \
            FOR { \
                res |= m(S1, S2); \
            } \
        } \
        else { \
            FOR { \
                res |= mn(S1, S2, len); \
            } \
        } \
        clock_gettime(CLOCK_MONOTONIC, &tve); \
        \
        diff  = (int64_t)tve.tv_sec * 1000000000L + tve.tv_nsec; \
        diff -= (int64_t)tvs.tv_sec * 1000000000L + tvs.tv_nsec; \
        printf("time=%.2lld.%.9lld, res=%d%s\n", \
               (long long)diff / 1000000000L, \
               (long long)diff % 1000000000L, \
               res, match ? "" : " != str[n]casecmp()'s result!"); \
        fflush(stdout); \
    } \
} while (0)

int main(int argc, char *argv[])
{
    char *ptr;

    if (argc < 6) {
        printf("%s <*=all; -=std; n++=nth> <nb iter> S1 S2 <nb char to compare or \\0>\n", PROG);
        return 0;
    }

    setlocale(LC_ALL, "");
    printf("%s '%s' %s \"%s\" \"%s\" %s: locale \"%s\"\n",
           argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
           setlocale(LC_ALL, NULL));
    fflush(stdout);

    /* last char of S1 is burnt */
    ptr = malloc(strlen(argv[3]) + 2);
    memcpy(ptr, argv[3], strlen(argv[3]));
    ptr[strlen(argv[3]) + 1] = '\0';
    ptr[strlen(argv[3])] = !'\0';
    argv[3] = ptr;

    /* last char of S2 is burnt */
    ptr = malloc(strlen(argv[4]) + 2);
    memcpy(ptr, argv[4], strlen(argv[4]));
    ptr[strlen(argv[4]) + 1] = '\0';
    ptr[strlen(argv[4])] = !'\0';
    argv[4] = ptr;

    RUN(ap_casecmpstr,   ap_casecmpstrn,   '0');
    RUN(ap_casecmpstr_1, ap_casecmpstrn_1, '1');
    RUN(ap_casecmpstr_2, ap_casecmpstrn_2, '2');
    RUN(ap_casecmpstr_4, ap_casecmpstrn_4, '4');
    RUN(ap_casecmpstr_3, ap_casecmpstrn_3, '3');
    RUN(ap_casecmpstr_7, ap_casecmpstrn_7, '7');
    RUN(ap_casecmpstr_5, ap_casecmpstrn_5, '5');
    RUN(ap_casecmpstr_6, ap_casecmpstrn_6, '6');

    RUN(svn_cstring_casecmp, svn_cstring_ncasecmp, 'v');

    RUN(mi_strcasecmp, mi_strncasecmp, 'm');

    RUN(strcasecmp_ext, strncasecmp_ext, 's');
    RUN(strcasecmp, strncasecmp, 's');
    RUN(strcmp, strncmp, 's');

    return 0;
}

Attachment: ap_casecmpstr.sh
Description: Bourne shell script

#include <stdlib.h>
#include <string.h>
#include <strings.h>

/*
 * Provide our own known-fast implementation of str[n]casecmp()
 * NOTE: ASCII only!
 */
static const unsigned char ucharmap[] = {
    0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
    0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    0x40,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
     'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
     'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
     'x',  'y',  'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
    0x60,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
     'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
     'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
     'x',  'y',  'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};

int ap_casecmpstr(const char *s1, const char *s2)
{
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    while (ucharmap[*ps1] == ucharmap[*ps2++]) {
        if (*ps1++ == '\0') {
            return (0);
        }
    }
    return (ucharmap[*ps1] - ucharmap[*--ps2]);
}

int ap_casecmpstrn(const char *s1, const char *s2, size_t n)
{
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;
    while (n--) {
        if (ucharmap[*ps1] != ucharmap[*ps2++]) {
            return (ucharmap[*ps1] - ucharmap[*--ps2]);
        }
        if (*ps1++ == '\0') {
            break;
        }
    }
    return (0);
}

int ap_casecmpstr_1(const char *s1, const char *s2)
{
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    while (ucharmap[*ps1] == ucharmap[*ps2]) {
        if (*ps1 == '\0') {
            return (0);
        }
        ++ps1;
        ++ps2;
    }
    return (ucharmap[*ps1] - ucharmap[*ps2]);
}

int ap_casecmpstrn_1(const char *s1, const char *s2, size_t n)
{
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;
    while (n--) {
        if (ucharmap[*ps1] != ucharmap[*ps2]) {
            return (ucharmap[*ps1] - ucharmap[*ps2]);
        }
        if (*ps1 == '\0') {
            break;
        }
        ++ps1;
        ++ps2;
    }
    return (0);
}

int ap_casecmpstr_2(const char *s1, const char *s2)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; ; ++i) {
        int c1 = ucharmap[ps1[i]];
        int c2 = ucharmap[ps2[i]];

        if (c1 != c2) {
            return c1 - c2;
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstrn_2(const char *s1, const char *s2, size_t n)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; i < n; ++i) {
        int c1 = ucharmap[ps1[i]];
        int c2 = ucharmap[ps2[i]];

        if (c1 != c2) {
            return c1 - c2;
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstr_3(const char *s1, const char *s2)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; ; ++i) {
        int c1 = ucharmap[ps1[i]];
        int c2 = ucharmap[ps2[i]];

        /* Above lookups are optimized away if first test below fails */
        if (ps1[i] != ps2[i] && c1 != c2) {
            return c1 - c2;
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstrn_3(const char *s1, const char *s2, size_t n)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; i < n; ++i) {
        int c1 = ucharmap[ps1[i]];
        int c2 = ucharmap[ps2[i]];

        /* Above lookups are optimized away if first test below fails */
        if (ps1[i] != ps2[i] && c1 != c2) {
            return c1 - c2;
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstr_4(const char *s1, const char *s2)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; ; ++i) {
        int c1 = ps1[i],
            c2 = ps2[i];
        if (c1 != c2) {
            c1 = ucharmap[c1];
            c2 = ucharmap[c2];
            if (c1 != c2) {
                return c1 - c2;
            }
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstrn_4(const char *s1, const char *s2, size_t n)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; i < n; ++i) {
        int c1 = ps1[i],
            c2 = ps2[i];
        if (c1 != c2) {
            c1 = ucharmap[c1];
            c2 = ucharmap[c2];
            if (c1 != c2) {
                return c1 - c2;
            }
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstr_5(const char *s1, const char *s2)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; ; ++i) {
        int c1 = ps1[i];
        if (c1 != ps2[i]) {
            int c2 = ucharmap[ps2[i]];
            if (ucharmap[c1] != c2) {
                return ucharmap[c1] - c2;
            }
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstrn_5(const char *s1, const char *s2, size_t n)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; i < n; ++i) {
        int c1 = ps1[i];
        if (c1 != ps2[i]) {
            int c2 = ucharmap[ps2[i]];
            c1 = ucharmap[c1];
            if (c1 != c2) {
                return c1 - c2;
            }
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstr_6(const char *s1, const char *s2)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0 ;; ++i) {
        int c1 = ps1[i],
            c2 = ps2[i];
        if (c1 != c2) {
            c1 += (c1 >= 'A' && c1 <= 'Z') << 5;
            c2 += (c2 >= 'A' && c2 <= 'Z') << 5;
            if (c1 != c2) {
                return c1 - c2;
            }
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstrn_6(const char *s1, const char *s2, size_t n)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; i < n; ++i) {
        int c1 = ps1[i],
            c2 = ps2[i];
        if (c1 != c2) {
            c1 += (c1 >= 'A' && c1 <= 'Z') << 5;
            c2 += (c2 >= 'A' && c2 <= 'Z') << 5;
            if (c1 != c2) {
                return c1 - c2;
            }
        }
        if (!c1) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstr_7(const char *s1, const char *s2)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; ; ++i) {
        if (ps1[i] != ps2[i] && ucharmap[ps1[i]] != ucharmap[ps2[i]]) {
            return ucharmap[ps1[i]] - ucharmap[ps2[i]];
        }
        if (!ps1[i]) {
            break;
        }
    }
    return (0);
}

int ap_casecmpstrn_7(const char *s1, const char *s2, size_t n)
{
    size_t i;
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (i = 0; i < n; ++i) {
        if (ps1[i] != ps2[i] && ucharmap[ps1[i]] != ucharmap[ps2[i]]) {
            return ucharmap[ps1[i]] - ucharmap[ps2[i]];
        }
        if (!ps1[i]) {
            break;
        }
    }
    return (0);
}


/*
 * svn's
 */

int svn_ctype_casecmp(int a, int b)
{
  const int A = ucharmap[(unsigned char)a];
  const int B = ucharmap[(unsigned char)b];
  return A - B;
}

int svn_cstring_casecmp(const char *str1, const char *str2)
{
    for (;;)
    {
        const int a = *str1++;
        const int b = *str2++;
        const int cmp = svn_ctype_casecmp(a, b);
        if (cmp || !a || !b)
            return cmp;
    }
}

int svn_cstring_ncasecmp(const char *str1, const char *str2, size_t n)
{
    while (n--)
    {
        const int a = *str1++;
        const int b = *str2++;
        const int cmp = svn_ctype_casecmp(a, b);
        if (cmp || !a || !b)
            return cmp;
    }
    return 0;
}


/*
 * mi's
 */

int mi_strcasecmp(const char *s1, const char *s2)
{
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    for (;;) {
        int	diff = *ps1 - *ps2;
        switch (diff) {
        case 0:
            break;
        case 'A' - 'a':
            if (*ps1 <= 'Z' && *ps1 >= 'A')
                break;
            return 1;
        case 'a' - 'A':
            if (*ps2 <= 'Z' && *ps2 >= 'A')
                break;
            return -1;
        default:
            /* Do, what tolower() would've done */
            if (*ps1 <= 'z' && *ps1 >= 'a')
                diff -= ('a' - 'A');
            if (*ps2 <= 'z' && *ps2 >= 'a')
                diff += ('a' - 'A');
            return diff;
        }
        if (*ps1 == '\0') {
            break;
        }
        ++ps1;
        ++ps2;
    }
    return (0);
}

int mi_strncasecmp(const char *s1, const char *s2, size_t n)
{
    const unsigned char *ps1 = (const unsigned char *) s1;
    const unsigned char *ps2 = (const unsigned char *) s2;

    while (n--) {
        int diff = *ps1 - *ps2;
        switch (diff) {
        case 0:
            break;
        case 'A' - 'a':
            if (*ps1 <= 'Z' && *ps1 >= 'A')
                break;
            return 1;
        case 'a' - 'A':
            if (*ps2 <= 'Z' && *ps2 >= 'A')
                break;
            return -1;
        default:
            /* Do, what tolower() would've done */
            if (*ps1 <= 'z' && *ps1 >= 'a')
                diff -= ('a' - 'A');
            if (*ps2 <= 'z' && *ps2 >= 'a')
                diff += ('a' - 'A');
            return diff;
        }
        if (*ps1 == '\0') {
            break;
        }
        ++ps1;
        ++ps2;
    }
    return (0);
}


/*
 * standard (extern)
 */
int strcasecmp_ext(const char *s1, const char *s2)
{
    return strcasecmp(s1, s2);
}

int strncasecmp_ext(const char *s1, const char *s2, size_t n)
{
    return strncasecmp(s1, s2, n);
}

Reply via email to