From 68ad53407d8feefbfb2a1282d69da4ae9007766b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 18 Mar 2011 16:24:52 +0100 Subject: Add a test for QString::fromLatin1 performace alternatives --- tests/benchmarks/corelib/tools/qstring/data.h | 12 + .../corelib/tools/qstring/fromlatin1.cpp | 334 +++++++++++++++++++++ .../corelib/tools/qstring/generatelist_char.pl | 25 +- tests/benchmarks/corelib/tools/qstring/main.cpp | 52 ++++ tests/benchmarks/corelib/tools/qstring/qstring.pro | 2 +- 5 files changed, 414 insertions(+), 11 deletions(-) create mode 100644 tests/benchmarks/corelib/tools/qstring/fromlatin1.cpp mode change 100755 => 100644 tests/benchmarks/corelib/tools/qstring/generatelist_char.pl diff --git a/tests/benchmarks/corelib/tools/qstring/data.h b/tests/benchmarks/corelib/tools/qstring/data.h index 390d0d6..bd4ff55 100644 --- a/tests/benchmarks/corelib/tools/qstring/data.h +++ b/tests/benchmarks/corelib/tools/qstring/data.h @@ -55,4 +55,16 @@ extern const ushort stringCollectionData[]; extern const StringCollection stringCollection[]; extern const int stringCollectionCount; +struct StringData +{ + const int *entries; + union { + const char *charData; + const ushort *ushortData; + }; + + int entryCount; + int maxLength; +}; + #endif // DATA_H diff --git a/tests/benchmarks/corelib/tools/qstring/fromlatin1.cpp b/tests/benchmarks/corelib/tools/qstring/fromlatin1.cpp new file mode 100644 index 0000000..63fcc01 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstring/fromlatin1.cpp @@ -0,0 +1,334 @@ +// This is a generated file - DO NOT EDIT + +#include "data.h" + +static const char charData[] __attribute__((aligned(64))) = { + // #0 + "\377\376\375\374\373\372\371\370" + ":/qt/etc/qt.conf" + "\377\376\375\374\373\372\371\370" // 32 + + // #1 + "\377\376\375\374\373\372\371\370" + "nb_NO.UTF-8" + "\377\376\375\374\373\372\371\370\367\366\365\364\363" // 64 + + // #2 + "\377\376\375\374\373\372\371\370" + "/proc/%1/exe" + "\377\376\375\374\373\372\371\370\367\366\365\364" // 96+ + + // #3 + "\377\376\375\374" + "*" + "\377\376\375\374\373\372\371\370\367\366\365" // 112 + + // #4 + "\377\376\375\374\373\372\371\370\367\366\365\364" + "qt.conf" + "\377\376\375\374\373\372\371\370\367\366\365\364\363" // 144 + + // #5 + "\377\376\375\374" + "*" + "\377\376\375\374\373\372\371\370\367\366\365" // 160 + + // #6 + "\377\376\375\374" + "*" + "\377\376\375\374\373\372\371\370\367\366\365" // 176 + + // #7 + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361\360" + "/usr/lib/qt4/plugins:/home/tmacieir/.kde/lib/kde4/plugins/:/home/tmacieir/KDE4/lib/kde4/plugins/:/usr/lib/kde4/plugins/" + "\377\376\375\374\373\372\371\370\367" // 320+ + + // #8 + "\377\376\375\374" + "*" + "\377\376\375\374\373\372\371\370\367\366\365" // 336 + + // #9 + "\377\376\375\374" + "*" + "\377\376\375\374\373\372\371\370\367\366\365" // 352 + + // #10 + "\377\376\375\374" + "*" + "\377\376\375\374\373\372\371\370\367\366\365" // 368 + + // #11 + "\377\376\375\374" + "*" + "\377\376\375\374\373\372\371\370\367\366\365" // 384 + + // #12 + "\377\376\375\374\373" + "trolltech.com" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362" // 416+ + + // #13 + "\377\376\375" + "Trolltech" + "\377\376\375\374" // 432 + + // #14 + "\377\376\375\374\373\372\371\370\367\366\365\364\363" + "TeamBuilder Client" + "\377" // 464 + + // #15 + "\377\376\375\374\373\372\371" + "0.0.0.0" + "\377\376" // 480 + + // #16 + "\377\376\375\374\373" + "." + "\377\376\375\374\373\372\371\370\367\366" // 496 + + // #17 + "\377\376\375\374\373\372\371\370" + "Unknown error" + "\377\376\375\374\373\372\371\370\367\366\365" // 528 + + // #18 + "\377\376\375\374\373\372\371\370\367" + "127.0.0.1" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362" // 560 + + // #19 + "\377\376\375\374\373" + "." + "\377\376\375\374\373\372\371\370\367\366" // 576 + + // #20 + "\377\376\375" + "::1" + "\377\376\375\374\373\372\371\370\367\366" // 592 + + // #21 + "\377\376\375\374\373\372\371" + ":" + "\377\376\375\374\373\372\371\370" // 608 + + // #22 + "\377\376\375\374\373\372\371\370\367" + "::" + "\377\376\375\374\373" // 624 + + // #23 + "lo" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362" // 640 + + // #24 + "\377\376\375\374\373\372\371\370\367\366\365\364" + "eth0" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361\360" // 672 + + // #25 + "\377\376\375\374\373\372\371\370" + "eth1" + "\377\376\375\374" // 688 + + // #26 + "\377\376\375\374" + "vboxnet0" + "\377\376\375\374" // 704 + + // #27 + "\377\376\375\374\373\372\371\370\367\366" + "." + "\377\376\375\374\373" // 720 + + // #28 + "\377\376\375\374\373\372\371\370\367\366\365\364\363" + "." + "\377\376" // 736 + + // #29 + "." + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361" // 752 + + // #30 + "\377\376\375\374\373" + "." + "\377\376\375\374\373\372\371\370\367\366" // 768 + + // #31 + "\377\376\375\374\373\372\371\370\367" + "127.0.0.1" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362" // 800 + + // #32 + "\377\376\375\374\373" + "." + "\377\376\375\374\373\372\371\370\367\366" // 816 + + // #33 + "\377\376\375" + "::1" + "\377\376\375\374\373\372\371\370\367\366" // 832 + + // #34 + "\377\376\375\374\373\372\371" + ":" + "\377\376\375\374\373\372\371\370" // 848 + + // #35 + "\377\376\375\374\373\372\371\370\367" + "::" + "\377\376\375\374\373" // 864 + + // #36 + "\377\376\375\374\373" + "." + "\377\376\375\374\373\372\371\370\367\366" // 880 + + // #37 + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361\360\357\356\355\354\353\352\351\350\347\346\345\344" + "Unknown error" + "\377\376\375\374\373\372\371" // 928+ + + // #38 + "\377\376\375\374\373\372\371\370" + "Unknown error" + "\377\376\375\374\373\372\371\370\367\366\365" // 960 + + // #39 + "\377\376\375\374\373\372\371\370\367" + "127.0.0.1" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362" // 992 + + // #40 + "\377\376\375\374\373" + "." + "\377\376\375\374\373\372\371\370\367\366" // 1008 + + // #41 + "\377\376\375" + "::1" + "\377\376\375\374\373\372\371\370\367\366" // 1024 + + // #42 + "\377\376\375\374\373\372\371" + ":" + "\377\376\375\374\373\372\371\370" // 1040 + + // #43 + "\377\376\375\374\373\372\371\370\367" + "::" + "\377\376\375\374\373" // 1056 + + // #44 + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361\360\357\356\355\354\353\352\351\350\347\346\345\344\343\342\341\340\337\336\335\334\333\332\331\330" + "Invalid socket descriptor" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361" // 1136+ + + // #45 + "\377\376\375\374\373\372\371\370\367" + "127.0.0.1" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362" // 1168 + + // #46 + "\377\376\375\374\373" + "." + "\377\376\375\374\373\372\371\370\367\366" // 1184 + + // #47 + "\377\376\375" + "::1" + "\377\376\375\374\373\372\371\370\367\366" // 1200 + + // #48 + "\377\376\375\374\373\372\371" + ":" + "\377\376\375\374\373\372\371\370" // 1216 + + // #49 + "\377\376\375\374\373\372\371\370\367" + "::" + "\377\376\375\374\373" // 1232 + + // #50 + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361\360\357\356\355\354\353\352\351\350\347\346\345\344\343\342\341\340\337\336\335\334\333\332\331\330\327\326\325\324\323\322\321\320\317\316\315\314\313\312\311\310\307\306\305\304" + "The remote host closed the connection" + "\377\376\375\374\373\372\371\370\367\366\365\364\363\362\361" // 1344+ + +}; +static const int intData[] = { + 16, 8, 8, 2760, 2760, // #0 + 11, 40, 40, 3080, 3080, // #1 + 12, 72, 72, 2232, 2232, // #2 + 1, 100, 100, 2164, 2164, // #3 + 7, 124, 124, 2780, 2780, // #4 + 1, 148, 148, 2164, 2164, // #5 + 1, 164, 164, 2164, 2164, // #6 + 119, 192, 192, 3280, 3280, // #7 + 1, 324, 324, 2164, 2164, // #8 + 1, 340, 340, 2164, 2164, // #9 + 1, 356, 356, 2164, 2164, // #10 + 1, 372, 372, 2164, 2164, // #11 + 13, 389, 389, 2229, 2229, // #12 + 9, 419, 419, 2243, 2243, // #13 + 18, 445, 445, 2253, 2253, // #14 + 7, 471, 471, 2391, 2391, // #15 + 1, 485, 485, 2261, 2261, // #16 + 13, 504, 504, 2200, 2200, // #17 + 9, 537, 537, 2377, 2377, // #18 + 1, 565, 565, 2261, 2261, // #19 + 3, 579, 579, 2387, 2387, // #20 + 1, 599, 599, 2263, 2263, // #21 + 2, 617, 617, 2265, 2265, // #22 + 2, 624, 624, 3088, 3088, // #23 + 4, 652, 652, 3244, 3244, // #24 + 4, 680, 680, 3400, 3400, // #25 + 8, 692, 692, 3556, 3556, // #26 + 1, 714, 714, 2426, 2426, // #27 + 1, 733, 733, 2429, 2429, // #28 + 1, 736, 736, 2432, 2432, // #29 + 1, 757, 757, 2261, 2261, // #30 + 9, 777, 777, 2377, 2377, // #31 + 1, 805, 805, 2261, 2261, // #32 + 3, 819, 819, 2387, 2387, // #33 + 1, 839, 839, 2263, 2263, // #34 + 2, 857, 857, 2265, 2265, // #35 + 1, 869, 869, 2261, 2261, // #36 + 13, 908, 908, 3004, 3004, // #37 + 13, 936, 936, 2200, 2200, // #38 + 9, 969, 969, 2377, 2377, // #39 + 1, 997, 997, 2261, 2261, // #40 + 3, 1011, 1011, 2387, 2387, // #41 + 1, 1031, 1031, 2263, 2263, // #42 + 2, 1049, 1049, 2265, 2265, // #43 + 25, 1096, 1096, 2744, 2744, // #44 + 9, 1145, 1145, 2377, 2377, // #45 + 1, 1173, 1173, 2261, 2261, // #46 + 3, 1187, 1187, 2387, 2387, // #47 + 1, 1207, 1207, 2263, 2263, // #48 + 2, 1225, 1225, 2265, 2265, // #49 + 37, 1292, 1292, 2604, 2604, // #50 +}; + +struct StringData fromLatin1Data = { + intData, + { charData }, + 51, /* entryCount */ + 119 /* maxLength */ +}; + +// average comparison length: 8.0000 +// cache-line crosses: 6 (5.9%) +// alignment histogram: +// 0xXXX0 = 6 (5.9%) strings, 3 (50.0%) of which same-aligned +// 0xXXX3 = 10 (9.8%) strings, 5 (50.0%) of which same-aligned +// 0xXXX4 = 16 (15.7%) strings, 8 (50.0%) of which same-aligned +// 0xXXX5 = 16 (15.7%) strings, 8 (50.0%) of which same-aligned +// 0xXXX7 = 10 (9.8%) strings, 5 (50.0%) of which same-aligned +// 0xXXX8 = 14 (13.7%) strings, 7 (50.0%) of which same-aligned +// 0xXXX9 = 16 (15.7%) strings, 8 (50.0%) of which same-aligned +// 0xXXXa = 2 (2.0%) strings, 1 (50.0%) of which same-aligned +// 0xXXXc = 8 (7.8%) strings, 4 (50.0%) of which same-aligned +// 0xXXXd = 4 (3.9%) strings, 2 (50.0%) of which same-aligned +// total = 102 (100%) strings, 51 (50.0%) of which same-aligned diff --git a/tests/benchmarks/corelib/tools/qstring/generatelist_char.pl b/tests/benchmarks/corelib/tools/qstring/generatelist_char.pl old mode 100755 new mode 100644 index 1c7003a..077174d --- a/tests/benchmarks/corelib/tools/qstring/generatelist_char.pl +++ b/tests/benchmarks/corelib/tools/qstring/generatelist_char.pl @@ -90,10 +90,10 @@ sub printCharArray($$$) { print " \""; for ($i = 0; $i < $len; $i++) { $c = substr($str, $i, 1); - if (ord($c) >= 0x20 && ord($c) <= 0x7f) { - print $c; - } else { + if (ord($c) < 0x20 || ord($c) > 0x7f || $c eq '"' || $c eq '\\') { printf "\\%o\"\"", ord($c); + } else { + print $c; } } @@ -115,7 +115,7 @@ print "// This is a generated file - DO NOT EDIT\n\n"; print "#include \"data.h\"\n\n"; $varname = shift @ARGV; -print "const char " . $varname . "Data[] __attribute__((aligned(64))) = {\n"; +print "static const char charData[] __attribute__((aligned(64))) = {\n"; $count = 0; $offset = 0; $totalsize = 0; @@ -169,23 +169,28 @@ while (1) { print "};\n"; close IN; -print "const struct StringCollection " . $varname . "[] = {\n"; +print "static const int intData[] = {\n"; for $i (0..$count-1) { - print " {", + print " ", $data[$i]->{len}, ", ", $data[$i]->{offset1}, ", ", $data[$i]->{offset2}, ", ", $data[$i]->{align1}, ", ", $data[$i]->{align2}, - "}, // #$i\n"; + ", // #$i\n"; next if $data[$i]->{len} == 0; die if (($data[$i]->{offset1} & 0xf) != ($data[$i]->{align1} & 0xf)); die if (($data[$i]->{offset2} & 0xf) != ($data[$i]->{align2} & 0xf)); } -print "};\n"; +print "};\n\n"; + +print "struct StringData $varname = {\n" . + " intData,\n" . + " { charData },\n" . + " $count, /* entryCount */\n" . + " $maxlen /* maxLength */\n" . + "};\n\n"; -print "const int " . $varname . "Count = $count;\n"; -print "const int " . $varname . "MaxLen = $maxlen;\n"; printf "// average comparison length: %.4f\n", ($totalsize * 1.0 / $count); printf "// cache-line crosses: %d (%.1f%%)\n", $cachelinecrosses, ($cachelinecrosses * 100.0 / $count / 2); diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp index c70b4c0..f957eee 100644 --- a/tests/benchmarks/corelib/tools/qstring/main.cpp +++ b/tests/benchmarks/corelib/tools/qstring/main.cpp @@ -72,6 +72,8 @@ private slots: void fromUtf8() const; void fromLatin1_data() const; void fromLatin1() const; + void fromLatin1Alternatives_data() const; + void fromLatin1Alternatives() const; }; void tst_QString::equals() const @@ -1440,6 +1442,56 @@ void tst_QString::fromLatin1() const } } +void fromLatin1_regular(QChar *dst, const char *str, int size) +{ + // from qstring.cpp: + while (size--) + *dst++ = (uchar)*str++; +} + +typedef void (* FromLatin1Function)(QChar *, const char *, int); +Q_DECLARE_METATYPE(FromLatin1Function) + +void tst_QString::fromLatin1Alternatives_data() const +{ + QTest::addColumn("function"); + QTest::newRow("regular") << &fromLatin1_regular; +} + +static void fromLatin1Alternatives_internal(FromLatin1Function function, bool doVerify) +{ + extern StringData fromLatin1Data; + struct Entry + { + int len; + int offset1, offset2; + int align1, align2; + }; + const Entry *entries = reinterpret_cast(fromLatin1Data.entries); + + for (int i = 0; i < fromLatin1Data.entryCount; ++i) { + int len = entries[i].len; + const char *src = fromLatin1Data.charData + entries[i].offset1; + + QString dst; + dst.resize(len); + (function)(dst.data(), src, len); + + if (doVerify) { + QCOMPARE(dst, QString::fromLatin1(src, len)); + } + } +} + +void tst_QString::fromLatin1Alternatives() const +{ + QFETCH(FromLatin1Function, function); + fromLatin1Alternatives_internal(function, true); + QBENCHMARK { + fromLatin1Alternatives_internal(function, false); + } +} + QTEST_MAIN(tst_QString) #include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qstring/qstring.pro b/tests/benchmarks/corelib/tools/qstring/qstring.pro index e43e400..e7ba04f 100644 --- a/tests/benchmarks/corelib/tools/qstring/qstring.pro +++ b/tests/benchmarks/corelib/tools/qstring/qstring.pro @@ -1,7 +1,7 @@ load(qttest_p4) TARGET = tst_bench_qstring QT -= gui -SOURCES += main.cpp data.cpp +SOURCES += main.cpp data.cpp fromlatin1.cpp wince*:{ DEFINES += SRCDIR=\\\"\\\" -- cgit v0.12