private import std.c.stdio; private import std.c.stdlib; private import std.c.string; private import std.perf; private import std.stdio; /* The original function in dmd phobos, as of dmd v0.162: int icmp(char[] s1, char[] s2) { auto len = s1.length; int result; if (s2.length < len) len = s2.length; version (Win32) { result = memicmp(s1, s2, len); } version (linux) { for (size_t i = 0; i < len; i++) { if (s1[i] != s2[i]) { char c1 = s1[i]; char c2 = s2[i]; if (c1 >= 'A' && c1 <= 'Z') c1 += cast(int)'a' - cast(int)'A'; if (c2 >= 'A' && c2 <= 'Z') c2 += cast(int)'a' - cast(int)'A'; result = cast(int)c1 - cast(int)c2; if (result) break; } } } if (result == 0) result = cast(int)s1.length - cast(int)s2.length; return result; } */ void main() { int iterations = 1000000; // worst-case scenario where strings have highly divergent capitalization. char[] string1a = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char[] string1b = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz " "ABCDEFGHIJKLMNOPQRSTUVWXYz abcdefghijklmnopqrstuvwxyz"; // to test cases where case sensitivity is not in question. char[] string2a = "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz"; char[] string2b = "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz"; PerformanceCounter SpeedTester = new PerformanceCounter(); writefln( "The following tests involve a worst-case scenario where strings that" " have highly divergent capitalization are compared." ); SpeedTester.start(); for( int i = 0; i < iterations; i++ ) { int result = icmpWin( string1a, string1b ); assert ( result == 0 ); } SpeedTester.stop(); writefln( SpeedTester.microseconds(), " - current Phobos on Win32 systems using memicmp function." ); SpeedTester.start(); for( int i = 0; i < iterations; i++ ) { int result = icmpUnix( string1a, string1b ); assert ( result == 0 ); } SpeedTester.stop(); writefln( SpeedTester.microseconds(), " - current Phobos on *nix systems using D implementation." ); SpeedTester.start(); for( int i = 0; i < iterations; i++ ) { int result = icmpNew( string1a, string1b ); assert ( result == 0 ); } SpeedTester.stop(); writefln( SpeedTester.microseconds(), " - possible new implementation." ); writefln( "Begin tests where the strings have identical capitalization already." ); SpeedTester.start(); for( int i = 0; i < iterations; i++ ) { int result = icmpWin( string2a, string2b ); assert ( result == 0 ); } SpeedTester.stop(); writefln( SpeedTester.microseconds(), " - current Phobos on Win32 systems using memicmp function." ); SpeedTester.start(); for( int i = 0; i < iterations; i++ ) { int result = icmpUnix( string2a, string2b ); assert ( result == 0 ); } SpeedTester.stop(); writefln( SpeedTester.microseconds(), " - current Phobos on *nix systems using D implementation." ); SpeedTester.start(); for( int i = 0; i < iterations; i++ ) { int result = icmpNew( string2a, string2b ); assert ( result == 0 ); } SpeedTester.stop(); writefln( SpeedTester.microseconds(), " - possible new implementation." ); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- //-------------------------------------------------------------------- int icmpWin(char[] s1, char[] s2) { auto len = s1.length; int result; if (s2.length < len) len = s2.length; result = memicmp(s1, s2, len); if (result == 0) result = cast(int)s1.length - cast(int)s2.length; return result; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- //-------------------------------------------------------------------- int icmpUnix(char[] s1, char[] s2) { auto len = s1.length; int result; if (s2.length < len) len = s2.length; for (size_t i = 0; i < len; i++) { if (s1[i] != s2[i]) { char c1 = s1[i]; char c2 = s2[i]; if (c1 >= 'A' && c1 <= 'Z') c1 += cast(int)'a' - cast(int)'A'; if (c2 >= 'A' && c2 <= 'Z') c2 += cast(int)'a' - cast(int)'A'; result = cast(int)c1 - cast(int)c2; if (result) break; } } if (result == 0) result = cast(int)s1.length - cast(int)s2.length; return result; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- //-------------------------------------------------------------------- private char[256] toLowerCase; static this() { for ( int i = 0; i < 256; i++ ) { if (i >= 'A' && i <= 'Z') toLowerCase[i] = i + ('a' - 'A'); else toLowerCase[i] = i; } } int icmpNew(char[] s1, char[] s2) { auto len = s1.length; int result; if (s2.length < len) len = s2.length; for (size_t i = 0; i < len; i++) { char c1 = s1[i]; char c2 = s2[i]; if (c1 != c2) { result = cast(int)toLowerCase[c1] - cast(int)toLowerCase[c2]; if (result) break; } } if (result == 0) result = cast(int)s1.length - cast(int)s2.length; return result; }