summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/benchmarks/corelib/tools/qstring/data.cpp1283
-rw-r--r--tests/benchmarks/corelib/tools/qstring/main.cpp675
2 files changed, 1770 insertions, 188 deletions
diff --git a/tests/benchmarks/corelib/tools/qstring/data.cpp b/tests/benchmarks/corelib/tools/qstring/data.cpp
new file mode 100644
index 0000000..89f50d0
--- /dev/null
+++ b/tests/benchmarks/corelib/tools/qstring/data.cpp
@@ -0,0 +1,1283 @@
+static const ushort stringCollectionData[] __attribute__((aligned(16))) = {
+ // #0
+ 65535,
+ 99, 111, 109, 112, 105, 108, 101, 114, 32, 118, 101, 114, 115, 105, 111, 110, 115, 47,
+ 65535,65534,65533,65532,65531, // 24
+ 65535,65534,65533,65532,65531,
+ 99, 111, 109, 112, 105, 108, 101, 114, 32, 118, 101, 114, 115, 105, 111, 110, 115, 47,
+ 65535, // 48
+
+ // #1
+ 65535,65534,65533,65532,65531,
+ 99, 111, 109, 112, 105, 108, 101, 114, 32, 118, 101, 114, 115, 105, 111, 110, 115, 47,
+ 65535, // 72
+ 65535,65534,65533,65532,65531,
+ 67, 111, 109, 112, 105, 108, 101, 114, 32, 86, 101, 114, 115, 105, 111, 110, 115, 47,
+ 65535, // 96
+
+ // #2
+ 65535,
+ 99, 111, 109, 112, 105, 108, 101, 114, 32, 116, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47,
+ 65535,65534,65533, // 120
+ 65535,65534,65533,65532,65531,
+ 99, 111, 109, 112, 105, 108, 101, 114, 32, 116, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47,
+ 65535,65534,65533,65532,65531,65530,65529, // 152
+
+ // #3
+ 65535,65534,65533,65532,65531,
+ 99, 111, 109, 112, 105, 108, 101, 114, 32, 116, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47,
+ 65535,65534,65533,65532,65531,65530,65529, // 184
+ 65535,
+ 67, 111, 109, 112, 105, 108, 101, 114, 32, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47,
+ 65535,65534,65533, // 208
+
+ // #4
+ 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523,65522,65521,65520,65519,
+ 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102,
+ 65535,65534,65533,65532, // 280+
+
+
+ // #5
+ 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523,
+ 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 352+
+ 65535,
+ 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102,
+ 65535,65534,65533,65532, // 408+
+
+ // #6
+ 65535,65534,65533,65532,65531,65530,65529,65528,65527,
+ 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102,
+ 65535,65534,65533,65532, // 472+
+
+
+ // #7
+ 65535,
+ 97, 114, 99, 104, 105, 118, 101, 100, 32, 99, 111, 109, 112, 105, 108, 101, 114, 115, 47,
+ 65535,65534,65533,65532, // 496
+ 65535,65534,65533,65532,65531,
+ 97, 114, 99, 104, 105, 118, 101, 100, 32, 99, 111, 109, 112, 105, 108, 101, 114, 115, 47,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 528
+
+ // #8
+ 65535,65534,65533,65532,65531,
+ 97, 114, 99, 104, 105, 118, 101, 100, 32, 99, 111, 109, 112, 105, 108, 101, 114, 115, 47,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 560
+ 65535,65534,65533,65532,65531,
+ 65, 114, 99, 104, 105, 118, 101, 100, 32, 67, 111, 109, 112, 105, 108, 101, 114, 115, 47,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 592
+
+ // #9
+ 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523,65522,65521,65520,65519,
+ 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102,
+ 65535,65534,65533,65532, // 664+
+ 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523,
+ 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 736+
+
+ // #10
+ 65535,65534,65533,65532,65531,
+ 76, 105, 110, 117, 120,
+ 65535,65534,65533,65532,65531,65530, // 752
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 760
+
+ // #11
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 776
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 792
+
+ // #12
+ 65535,
+ 105, 99, 99,
+ 65535,65534,65533,65532, // 800
+ 65535,65534,65533,65532,65531,
+ 103, 43, 43,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 816
+
+ // #13
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 824
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 832
+
+ // #14
+ 65535,
+ 105, 51, 56, 54,
+ 65535,65534,65533, // 840
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 856
+
+ // #15
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 864
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 872
+
+ // #16
+ 65535,
+ 105, 51, 56, 54,
+ 65535,65534,65533, // 880
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 896
+
+ // #17
+ 65535,
+ 103, 99, 99,
+ 65535,65534,65533,65532, // 904
+ 65535,65534,65533,65532,65531,
+ 103, 43, 43,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 920
+
+ // #18
+ 65535,65534,65533,65532,65531,
+ 76, 105, 110, 117, 120,
+ 65535,65534,65533,65532,65531,65530, // 936
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 944
+
+ // #19
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 960
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 976
+
+ // #20
+ 65535,
+ 103, 43, 43,
+ 65535,65534,65533,65532, // 984
+ 65535,65534,65533,65532,65531,
+ 103, 43, 43,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 1000
+
+ // #21
+ 65535,65534,65533,65532,65531,
+ 52, 46, 52, 46, 51,
+ 65535,65534,65533,65532,65531,65530, // 1016
+ 65535,65534,65533,65532,65531,
+ 52, 46, 52, 46, 51,
+ 65535,65534,65533,65532,65531,65530, // 1032
+
+ // #22
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1040
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1048
+
+ // #23
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1064
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1080
+
+ // #24
+ 65535,
+ 47, 117, 115, 114, 47, 98, 105, 110, 47, 103, 43, 43,
+ 65535,65534,65533, // 1096
+ 65535,
+ 47, 117, 115, 114, 47, 98, 105, 110, 47, 103, 43, 43,
+ 65535,65534,65533, // 1112
+
+ // #25
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1120
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1128
+
+ // #26
+ 65535,
+ 105, 51, 56, 54,
+ 65535,65534,65533, // 1136
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1152
+
+ // #27
+ 65535,
+ 105, 99, 99,
+ 65535,65534,65533,65532, // 1160
+ 65535,65534,65533,65532,65531,
+ 103, 43, 43,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 1176
+
+ // #28
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1184
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1192
+
+ // #29
+ 65535,
+ 105, 51, 56, 54,
+ 65535,65534,65533, // 1200
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1216
+
+ // #30
+ 65535,65534,65533,65532,65531,
+ 76, 105, 110, 117, 120,
+ 65535,65534,65533,65532,65531,65530, // 1232
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1240
+
+ // #31
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1256
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1272
+
+ // #32
+ 65535,65534,65533,65532,65531,
+ 76, 105, 110, 117, 120,
+ 65535,65534,65533,65532,65531,65530, // 1288
+ 65535,
+ 76, 105, 110, 117, 120,
+ 65535,65534, // 1296
+
+ // #33
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1312
+ 65535,65534,65533,65532,65531,
+ 105, 51, 56, 54,
+ 65535,65534,65533,65532,65531,65530,65529, // 1328
+
+ // #34
+ 65535,
+ 45, 109, 97, 114, 99, 104, 61, 99, 111, 114, 101, 50,
+ 65535,65534,65533, // 1344
+ 65535,
+ 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105,
+ 65535,65534,65533, // 1360
+
+ // #35
+ 65535,65534,65533,65532,65531,
+ 45, 102, 108, 111, 111, 112, 45, 98, 108, 111, 99, 107,
+ 65535,65534,65533,65532,65531,65530,65529, // 1384
+ 65535,
+ 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105,
+ 65535,65534,65533, // 1400
+
+ // #36
+ 65535,65534,65533,65532,65531,
+ 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105,
+ 65535,65534,65533,65532,65531,65530,65529, // 1424
+ 65535,
+ 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105,
+ 65535,65534,65533, // 1440
+
+ // #37
+ 65535,65534,65533,65532,65531,
+ 45, 109, 115, 115, 101, 52,
+ 65535,65534,65533,65532,65531, // 1456
+ 65535,65534,65533,65532,65531,
+ 108, 101, 110, 103, 116, 104,
+ 65535,65534,65533,65532,65531, // 1472
+
+ // #38
+ 65535,65534,65533,65532,65531,
+ 116, 98, 51, 54, 57, 54, 56, 95, 49, 46, 111,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 1496
+ 65535,65534,65533,65532,65531,
+ 116, 98, 51, 54, 57, 54, 56, 95, 49, 46, 111,
+ 65535,65534,65533,65532,65531,65530,65529,65528, // 1520
+
+ // #39
+ 65535,65534,65533,65532,65531,
+ 68, 69, 83, 75, 84, 79, 80, 95, 83, 69, 83, 83,
+ 65535,65534,65533,65532,65531,65530,65529, // 1544
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1560
+
+ // #40
+ 65535,65534,65533,65532,65531,
+ 76, 67, 95, 83, 79, 85, 82, 67, 69, 68, 61, 49,
+ 65535,65534,65533,65532,65531,65530,65529, // 1584
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1600
+
+ // #41
+ 65535,65534,65533,65532,65531,
+ 81, 84, 68, 73, 82, 61, 47, 104, 111, 109, 101, 47,
+ 65535,65534,65533,65532,65531,65530,65529, // 1624
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1640
+
+ // #42
+ 65535,
+ 76, 67, 95, 67, 84, 89, 80, 69, 61, 112, 116, 95,
+ 65535,65534,65533, // 1656
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1672
+
+ // #43
+ 65535,
+ 71, 84, 75, 95, 82, 67, 95, 70, 73, 76, 69, 83,
+ 65535,65534,65533, // 1688
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1704
+
+ // #44
+ 65535,
+ 88, 77, 79, 68, 73, 70, 73, 69, 82, 83, 61, 64,
+ 65535,65534,65533, // 1720
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1736
+
+ // #45
+ 65535,
+ 83, 72, 69, 76, 76, 61, 47, 98, 105, 110, 47, 122,
+ 65535,65534,65533, // 1752
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1768
+
+ // #46
+ 65535,65534,65533,65532,65531,
+ 85, 61, 64, 123, 117, 112, 115, 116, 114, 101, 97, 109,
+ 65535,65534,65533,65532,65531,65530,65529, // 1792
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1808
+
+ // #47
+ 65535,
+ 95, 61, 47, 117, 115, 114, 47, 98, 105, 110, 47, 105,
+ 65535,65534,65533, // 1824
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1840
+
+ // #48
+ 65535,
+ 88, 68, 71, 95, 67, 79, 78, 70, 73, 71, 95, 68,
+ 65535,65534,65533, // 1856
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1872
+
+ // #49
+ 65535,65534,65533,65532,65531,
+ 83, 65, 86, 69, 72, 73, 83, 84, 61, 49, 48, 48,
+ 65535,65534,65533,65532,65531,65530,65529, // 1896
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1912
+
+ // #50
+ 65535,
+ 75, 68, 69, 95, 77, 85, 76, 84, 73, 72, 69, 65,
+ 65535,65534,65533, // 1928
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1944
+
+ // #51
+ 65535,65534,65533,65532,65531,
+ 77, 65, 76, 76, 79, 67, 95, 67, 72, 69, 67, 75,
+ 65535,65534,65533,65532,65531,65530,65529, // 1968
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 1984
+
+ // #52
+ 65535,65534,65533,65532,65531,
+ 72, 73, 83, 84, 67, 79, 78, 84, 82, 79, 76, 61,
+ 65535,65534,65533,65532,65531,65530,65529, // 2008
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2024
+
+ // #53
+ 65535,65534,65533,65532,65531,
+ 88, 68, 71, 95, 68, 65, 84, 65, 95, 68, 73, 82,
+ 65535,65534,65533,65532,65531,65530,65529, // 2048
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2064
+
+ // #54
+ 65535,65534,65533,65532,65531,
+ 88, 68, 77, 95, 77, 65, 78, 65, 71, 69, 68, 61,
+ 65535,65534,65533,65532,65531,65530,65529, // 2088
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2104
+
+ // #55
+ 65535,
+ 76, 67, 95, 67, 79, 76, 76, 65, 84, 69, 61, 112,
+ 65535,65534,65533, // 2120
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2136
+
+ // #56
+ 65535,
+ 81, 84, 95, 80, 76, 85, 71, 73, 78, 95, 80, 65,
+ 65535,65534,65533, // 2152
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2168
+
+ // #57
+ 65535,
+ 83, 67, 82, 69, 69, 78, 68, 73, 82, 61, 47, 104,
+ 65535,65534,65533, // 2184
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2200
+
+ // #58
+ 65535,65534,65533,65532,65531,
+ 76, 69, 83, 83, 79, 80, 69, 78, 61, 124, 47, 117,
+ 65535,65534,65533,65532,65531,65530,65529, // 2224
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2240
+
+ // #59
+ 65535,
+ 76, 67, 95, 78, 65, 77, 69, 61, 110, 98, 95, 78,
+ 65535,65534,65533, // 2256
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2272
+
+ // #60
+ 65535,65534,65533,65532,65531,
+ 80, 52, 67, 76, 73, 69, 78, 84, 61, 116, 109, 97,
+ 65535,65534,65533,65532,65531,65530,65529, // 2296
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2312
+
+ // #61
+ 65535,
+ 80, 65, 84, 72, 61, 47, 104, 111, 109, 101, 47, 116,
+ 65535,65534,65533, // 2328
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2344
+
+ // #62
+ 65535,65534,65533,65532,65531,
+ 71, 80, 71, 95, 65, 71, 69, 78, 84, 95, 73, 78,
+ 65535,65534,65533,65532,65531,65530,65529, // 2368
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2384
+
+ // #63
+ 65535,65534,65533,65532,65531,
+ 88, 67, 85, 82, 83, 79, 82, 95, 84, 72, 69, 77,
+ 65535,65534,65533,65532,65531,65530,65529, // 2408
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2424
+
+ // #64
+ 65535,65534,65533,65532,65531,
+ 83, 69, 83, 83, 73, 79, 78, 95, 77, 65, 78, 65,
+ 65535,65534,65533,65532,65531,65530,65529, // 2448
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2464
+
+ // #65
+ 65535,
+ 81, 84, 83, 82, 67, 68, 73, 82, 61, 47, 104, 111,
+ 65535,65534,65533, // 2480
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2496
+
+ // #66
+ 65535,65534,65533,65532,65531,
+ 87, 73, 78, 68, 79, 87, 73, 68, 61, 52, 54, 49,
+ 65535,65534,65533,65532,65531,65530,65529, // 2520
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2536
+
+ // #67
+ 65535,65534,65533,65532,65531,
+ 76, 67, 95, 77, 69, 83, 83, 65, 71, 69, 83, 61,
+ 65535,65534,65533,65532,65531,65530,65529, // 2560
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2576
+
+ // #68
+ 65535,
+ 76, 67, 95, 78, 85, 77, 69, 82, 73, 67, 61, 110,
+ 65535,65534,65533, // 2592
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2608
+
+ // #69
+ 65535,
+ 71, 84, 75, 50, 95, 82, 67, 95, 70, 73, 76, 69,
+ 65535,65534,65533, // 2624
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2640
+
+ // #70
+ 65535,
+ 80, 82, 79, 70, 73, 76, 69, 72, 79, 77, 69, 61,
+ 65535,65534,65533, // 2656
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2672
+
+ // #71
+ 65535,65534,65533,65532,65531,
+ 68, 77, 95, 67, 79, 78, 84, 82, 79, 76, 61, 47,
+ 65535,65534,65533,65532,65531,65530,65529, // 2696
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2712
+
+ // #72
+ 65535,
+ 76, 83, 95, 67, 79, 76, 79, 82, 83, 61, 114, 115,
+ 65535,65534,65533, // 2728
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2744
+
+ // #73
+ 65535,65534,65533,65532,65531,
+ 83, 83, 72, 95, 65, 85, 84, 72, 95, 83, 79, 67,
+ 65535,65534,65533,65532,65531,65530,65529, // 2768
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2784
+
+ // #74
+ 65535,65534,65533,65532,65531,
+ 75, 68, 69, 68, 73, 82, 83, 61, 47, 104, 111, 109,
+ 65535,65534,65533,65532,65531,65530,65529, // 2808
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2824
+
+ // #75
+ 65535,65534,65533,65532,65531,
+ 76, 68, 95, 80, 82, 69, 76, 79, 65, 68, 61, 47,
+ 65535,65534,65533,65532,65531,65530,65529, // 2848
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2864
+
+ // #76
+ 65535,65534,65533,65532,65531,
+ 88, 67, 85, 82, 83, 79, 82, 95, 80, 65, 84, 72,
+ 65535,65534,65533,65532,65531,65530,65529, // 2888
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2904
+
+ // #77
+ 65535,
+ 115, 114, 99, 100, 105, 114, 61, 47, 104, 111, 109, 101,
+ 65535,65534,65533, // 2920
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2936
+
+ // #78
+ 65535,65534,65533,65532,65531,
+ 72, 79, 77, 69, 61, 47, 104, 111, 109, 101, 47, 116,
+ 65535,65534,65533,65532,65531,65530,65529, // 2960
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 2976
+
+ // #79
+ 65535,
+ 81, 84, 52, 68, 79, 67, 68, 73, 82, 61, 47, 117,
+ 65535,65534,65533, // 2992
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3008
+
+ // #80
+ 65535,65534,65533,65532,65531,
+ 80, 87, 68, 61, 47, 104, 111, 109, 101, 47, 116, 109,
+ 65535,65534,65533,65532,65531,65530,65529, // 3032
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3048
+
+ // #81
+ 65535,65534,65533,65532,65531,
+ 75, 68, 69, 95, 83, 69, 83, 83, 73, 79, 78, 95,
+ 65535,65534,65533,65532,65531,65530,65529, // 3072
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3088
+
+ // #82
+ 65535,
+ 73, 78, 83, 73, 68, 69, 95, 83, 80, 69, 67, 73,
+ 65535,65534,65533, // 3104
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3120
+
+ // #83
+ 65535,
+ 83, 83, 72, 95, 65, 71, 69, 78, 84, 95, 80, 73,
+ 65535,65534,65533, // 3136
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3152
+
+ // #84
+ 65535,
+ 80, 75, 71, 95, 67, 79, 78, 70, 73, 71, 95, 80,
+ 65535,65534,65533, // 3168
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3184
+
+ // #85
+ 65535,65534,65533,65532,65531,
+ 68, 66, 85, 83, 95, 83, 69, 83, 83, 73, 79, 78,
+ 65535,65534,65533,65532,65531,65530,65529, // 3208
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3224
+
+ // #86
+ 65535,
+ 76, 68, 95, 76, 73, 66, 82, 65, 82, 89, 95, 80,
+ 65535,65534,65533, // 3240
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3256
+
+ // #87
+ 65535,65534,65533,65532,65531,
+ 80, 52, 85, 83, 69, 82, 61, 116, 106, 109, 97, 99,
+ 65535,65534,65533,65532,65531,65530,65529, // 3280
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3296
+
+ // #88
+ 65535,65534,65533,65532,65531,
+ 81, 84, 69, 83, 84, 95, 67, 79, 76, 79, 82, 69,
+ 65535,65534,65533,65532,65531,65530,65529, // 3320
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3336
+
+ // #89
+ 65535,65534,65533,65532,65531,
+ 88, 68, 71, 95, 83, 69, 83, 83, 73, 79, 78, 95,
+ 65535,65534,65533,65532,65531,65530,65529, // 3360
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3376
+
+ // #90
+ 65535,65534,65533,65532,65531,
+ 76, 69, 83, 83, 75, 69, 89, 61, 47, 101, 116, 99,
+ 65535,65534,65533,65532,65531,65530,65529, // 3400
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3416
+
+ // #91
+ 65535,
+ 76, 79, 71, 78, 65, 77, 69, 61, 116, 109, 97, 99,
+ 65535,65534,65533, // 3432
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3448
+
+ // #92
+ 65535,
+ 71, 95, 70, 73, 76, 69, 78, 65, 77, 69, 95, 69,
+ 65535,65534,65533, // 3464
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3480
+
+ // #93
+ 65535,
+ 75, 68, 69, 95, 70, 85, 76, 76, 95, 83, 69, 83,
+ 65535,65534,65533, // 3496
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3512
+
+ // #94
+ 65535,65534,65533,65532,65531,
+ 72, 79, 83, 84, 78, 65, 77, 69, 61, 108, 111, 116,
+ 65535,65534,65533,65532,65531,65530,65529, // 3536
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3552
+
+ // #95
+ 65535,65534,65533,65532,65531,
+ 76, 67, 95, 84, 73, 77, 69, 61, 112, 116, 95, 66,
+ 65535,65534,65533,65532,65531,65530,65529, // 3576
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3592
+
+ // #96
+ 65535,
+ 83, 83, 72, 95, 65, 83, 75, 80, 65, 83, 83, 61,
+ 65535,65534,65533, // 3608
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3624
+
+ // #97
+ 65535,65534,65533,65532,65531,
+ 72, 73, 83, 84, 70, 73, 76, 69, 61, 47, 104, 111,
+ 65535,65534,65533,65532,65531,65530,65529, // 3648
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3664
+
+ // #98
+ 65535,
+ 75, 79, 78, 83, 79, 76, 69, 95, 68, 66, 85, 83,
+ 65535,65534,65533, // 3680
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3696
+
+ // #99
+ 65535,
+ 77, 65, 75, 69, 61, 47, 117, 115, 114, 47, 98, 105,
+ 65535,65534,65533, // 3712
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3728
+
+ // #100
+ 65535,
+ 67, 65, 78, 66, 69, 82, 82, 65, 95, 68, 82, 73,
+ 65535,65534,65533, // 3744
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3760
+
+ // #101
+ 65535,
+ 71, 67, 79, 78, 70, 95, 84, 77, 80, 68, 73, 82,
+ 65535,65534,65533, // 3776
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3792
+
+ // #102
+ 65535,65534,65533,65532,65531,
+ 85, 83, 69, 82, 61, 116, 109, 97, 99, 105, 101, 105,
+ 65535,65534,65533,65532,65531,65530,65529, // 3816
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3832
+
+ // #103
+ 65535,
+ 111, 98, 106, 100, 105, 114, 61, 47, 104, 111, 109, 101,
+ 65535,65534,65533, // 3848
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3864
+
+ // #104
+ 65535,65534,65533,65532,65531,
+ 76, 67, 95, 77, 79, 78, 69, 84, 65, 82, 89, 61,
+ 65535,65534,65533,65532,65531,65530,65529, // 3888
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3904
+
+ // #105
+ 65535,65534,65533,65532,65531,
+ 81, 84, 76, 73, 66, 61, 47, 117, 115, 114, 47, 108,
+ 65535,65534,65533,65532,65531,65530,65529, // 3928
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3944
+
+ // #106
+ 65535,65534,65533,65532,65531,
+ 76, 67, 95, 84, 69, 76, 69, 80, 72, 79, 78, 69,
+ 65535,65534,65533,65532,65531,65530,65529, // 3968
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 3984
+
+ // #107
+ 65535,
+ 80, 89, 84, 72, 79, 78, 68, 79, 78, 84, 87, 82,
+ 65535,65534,65533, // 4000
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4016
+
+ // #108
+ 65535,65534,65533,65532,65531,
+ 84, 77, 80, 68, 73, 82, 61, 47, 116, 109, 112, 47,
+ 65535,65534,65533,65532,65531,65530,65529, // 4040
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4056
+
+ // #109
+ 65535,65534,65533,65532,65531,
+ 65, 82, 77, 76, 77, 68, 95, 76, 73, 67, 69, 78,
+ 65535,65534,65533,65532,65531,65530,65529, // 4080
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4096
+
+ // #110
+ 65535,
+ 80, 89, 84, 72, 79, 78, 80, 65, 84, 72, 61, 47,
+ 65535,65534,65533, // 4112
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4128
+
+ // #111
+ 65535,65534,65533,65532,65531,
+ 77, 65, 75, 69, 70, 76, 65, 71, 83, 61, 119, 32,
+ 65535,65534,65533,65532,65531,65530,65529, // 4152
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4168
+
+ // #112
+ 65535,
+ 77, 70, 76, 65, 71, 83, 61, 45, 119, 32, 45, 45,
+ 65535,65534,65533, // 4184
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4200
+
+ // #113
+ 65535,
+ 77, 65, 73, 76, 61, 47, 118, 97, 114, 47, 115, 112,
+ 65535,65534,65533, // 4216
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4232
+
+ // #114
+ 65535,65534,65533,65532,65531,
+ 83, 72, 69, 76, 76, 95, 83, 69, 83, 83, 73, 79,
+ 65535,65534,65533,65532,65531,65530,65529, // 4256
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4272
+
+ // #115
+ 65535,
+ 75, 68, 69, 68, 73, 82, 61, 47, 104, 111, 109, 101,
+ 65535,65534,65533, // 4288
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4304
+
+ // #116
+ 65535,65534,65533,65532,65531,
+ 76, 69, 83, 83, 67, 72, 65, 82, 83, 69, 84, 61,
+ 65535,65534,65533,65532,65531,65530,65529, // 4328
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4344
+
+ // #117
+ 65535,65534,65533,65532,65531,
+ 76, 67, 95, 80, 65, 80, 69, 82, 61, 110, 98, 95,
+ 65535,65534,65533,65532,65531,65530,65529, // 4368
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4384
+
+ // #118
+ 65535,
+ 66, 82, 79, 87, 83, 69, 82, 61, 47, 117, 115, 114,
+ 65535,65534,65533, // 4400
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4416
+
+ // #119
+ 65535,
+ 77, 69, 84, 65, 95, 67, 76, 65, 83, 83, 61, 100,
+ 65535,65534,65533, // 4432
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4448
+
+ // #120
+ 65535,65534,65533,65532,65531,
+ 77, 68, 86, 95, 77, 69, 78, 85, 95, 83, 84, 89,
+ 65535,65534,65533,65532,65531,65530,65529, // 4472
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4488
+
+ // #121
+ 65535,65534,65533,65532,65531,
+ 67, 79, 76, 79, 82, 70, 71, 66, 71, 61, 49, 53,
+ 65535,65534,65533,65532,65531,65530,65529, // 4512
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4528
+
+ // #122
+ 65535,65534,65533,65532,65531,
+ 80, 89, 84, 72, 79, 78, 83, 84, 65, 82, 84, 85,
+ 65535,65534,65533,65532,65531,65530,65529, // 4552
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4568
+
+ // #123
+ 65535,
+ 76, 67, 95, 77, 69, 65, 83, 85, 82, 69, 77, 69,
+ 65535,65534,65533, // 4584
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4600
+
+ // #124
+ 65535,65534,65533,65532,65531,
+ 69, 68, 73, 84, 79, 82, 61, 47, 117, 115, 114, 47,
+ 65535,65534,65533,65532,65531,65530,65529, // 4624
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4640
+
+ // #125
+ 65535,65534,65533,65532,65531,
+ 69, 78, 95, 84, 66, 61, 109, 111, 99, 58, 117, 105,
+ 65535,65534,65533,65532,65531,65530,65529, // 4664
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4680
+
+ // #126
+ 65535,
+ 72, 73, 83, 84, 83, 73, 90, 69, 61, 49, 48, 48,
+ 65535,65534,65533, // 4696
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4712
+
+ // #127
+ 65535,65534,65533,65532,65531,
+ 71, 83, 95, 76, 73, 66, 61, 47, 104, 111, 109, 101,
+ 65535,65534,65533,65532,65531,65530,65529, // 4736
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4752
+
+ // #128
+ 65535,65534,65533,65532,65531,
+ 78, 76, 83, 80, 65, 84, 72, 61, 47, 117, 115, 114,
+ 65535,65534,65533,65532,65531,65530,65529, // 4776
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4792
+
+ // #129
+ 65535,65534,65533,65532,65531,
+ 87, 73, 78, 68, 79, 87, 80, 65, 84, 72, 61, 55,
+ 65535,65534,65533,65532,65531,65530,65529, // 4816
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4832
+
+ // #130
+ 65535,65534,65533,65532,65531,
+ 75, 79, 78, 83, 79, 76, 69, 95, 68, 66, 85, 83,
+ 65535,65534,65533,65532,65531,65530,65529, // 4856
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4872
+
+ // #131
+ 65535,
+ 76, 67, 95, 73, 68, 69, 78, 84, 73, 70, 73, 67,
+ 65535,65534,65533, // 4888
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4904
+
+ // #132
+ 65535,
+ 73, 78, 80, 85, 84, 82, 67, 61, 47, 101, 116, 99,
+ 65535,65534,65533, // 4920
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4936
+
+ // #133
+ 65535,65534,65533,65532,65531,
+ 81, 84, 73, 78, 67, 61, 47, 117, 115, 114, 47, 108,
+ 65535,65534,65533,65532,65531,65530,65529, // 4960
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 4976
+
+ // #134
+ 65535,
+ 76, 67, 95, 65, 68, 68, 82, 69, 83, 83, 61, 110,
+ 65535,65534,65533, // 4992
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5008
+
+ // #135
+ 65535,65534,65533,65532,65531,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 95,
+ 65535,65534,65533,65532,65531,65530,65529, // 5032
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5048
+
+ // #136
+ 65535,
+ 76, 65, 78, 71, 61, 112, 116, 95, 66, 82, 46, 85,
+ 65535,65534,65533, // 5064
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5080
+
+ // #137
+ 65535,
+ 80, 52, 80, 79, 82, 84, 61, 112, 52, 46, 116, 114,
+ 65535,65534,65533, // 5096
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5112
+
+ // #138
+ 65535,65534,65533,65532,65531,
+ 80, 73, 76, 79, 84, 80, 79, 82, 84, 61, 117, 115,
+ 65535,65534,65533,65532,65531,65530,65529, // 5136
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5152
+
+ // #139
+ 65535,
+ 75, 68, 69, 95, 83, 69, 83, 83, 73, 79, 78, 95,
+ 65535,65534,65533, // 5168
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5184
+
+ // #140
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5200
+ 65535,
+ 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61,
+ 65535,65534,65533, // 5216
+
+
+};
+static struct StringCollection
+{
+ int len;
+ int offset1, offset2;
+ ushort align1, align2;
+} stringCollection[] = {
+ {18, 1, 29, 3666, 106}, // #0
+ {18, 53, 77, 106, 1978}, // #1
+ {20, 97, 125, 2850, 3210}, // #2
+ {20, 157, 185, 3210, 3138}, // #3
+ {51, 225, 225, 3362, 3362}, // #4
+ {51, 293, 353, 1434, 3362}, // #5
+ {51, 417, 417, 3362, 3362}, // #6
+ {19, 473, 501, 2850, 10}, // #7
+ {19, 533, 565, 10, 442}, // #8
+ {51, 609, 677, 3362, 1434}, // #9
+ {5, 741, 753, 2666, 2066}, // #10
+ {4, 765, 781, 2362, 3930}, // #11
+ {3, 793, 805, 3330, 2138}, // #12
+ {5, 817, 825, 738, 2066}, // #13
+ {4, 833, 845, 434, 3930}, // #14
+ {5, 857, 865, 3842, 2066}, // #15
+ {4, 873, 885, 3538, 3930}, // #16
+ {3, 897, 909, 3330, 2138}, // #17
+ {5, 925, 937, 1898, 2066}, // #18
+ {4, 949, 965, 1594, 3930}, // #19
+ {3, 977, 989, 3330, 2138}, // #20
+ {5, 1005, 1021, 2218, 762}, // #21
+ {5, 1033, 1041, 3346, 2066}, // #22
+ {4, 1053, 1069, 3082, 3930}, // #23
+ {12, 1081, 1097, 2082, 962}, // #24
+ {5, 1113, 1121, 3362, 2066}, // #25
+ {4, 1129, 1141, 322, 3930}, // #26
+ {3, 1153, 1165, 2050, 2138}, // #27
+ {5, 1177, 1185, 1538, 2066}, // #28
+ {4, 1193, 1205, 1234, 3930}, // #29
+ {5, 1221, 1233, 554, 2066}, // #30
+ {4, 1245, 1261, 250, 3930}, // #31
+ {5, 1277, 1289, 2858, 2066}, // #32
+ {4, 1301, 1317, 2554, 3930}, // #33
+ {12, 1329, 1345, 2194, 1762}, // #34
+ {12, 1365, 1385, 2170, 1762}, // #35
+ {12, 1405, 1425, 2314, 1762}, // #36
+ {6, 1445, 1461, 3626, 666}, // #37
+ {11, 1477, 1501, 3882, 842}, // #38
+ {12, 1525, 1545, 1722, 2930}, // #39
+ {12, 1565, 1585, 1914, 2930}, // #40
+ {12, 1605, 1625, 442, 2930}, // #41
+ {12, 1641, 1657, 626, 2930}, // #42
+ {12, 1673, 1689, 946, 2930}, // #43
+ {12, 1705, 1721, 738, 2930}, // #44
+ {12, 1737, 1753, 2066, 2930}, // #45
+ {12, 1773, 1793, 1210, 2930}, // #46
+ {12, 1809, 1825, 1426, 2930}, // #47
+ {12, 1841, 1857, 1650, 2930}, // #48
+ {12, 1877, 1897, 1530, 2930}, // #49
+ {12, 1913, 1929, 1858, 2930}, // #50
+ {12, 1949, 1969, 2106, 2930}, // #51
+ {12, 1989, 2009, 2202, 2930}, // #52
+ {12, 2029, 2049, 2490, 2930}, // #53
+ {12, 2069, 2089, 2794, 2930}, // #54
+ {12, 2105, 2121, 2322, 2930}, // #55
+ {12, 2137, 2153, 2834, 2930}, // #56
+ {12, 2169, 2185, 1266, 2930}, // #57
+ {12, 2205, 2225, 2538, 2930}, // #58
+ {12, 2241, 2257, 2706, 2930}, // #59
+ {12, 2277, 2297, 3402, 2930}, // #60
+ {12, 2313, 2329, 146, 2930}, // #61
+ {12, 2349, 2369, 3690, 2930}, // #62
+ {12, 2389, 2409, 810, 2930}, // #63
+ {12, 2429, 2449, 1178, 2930}, // #64
+ {12, 2465, 2481, 1442, 2930}, // #65
+ {12, 2501, 2521, 3546, 2930}, // #66
+ {12, 2541, 2561, 1930, 2930}, // #67
+ {12, 2577, 2593, 1634, 2930}, // #68
+ {12, 2609, 2625, 1986, 2930}, // #69
+ {12, 2641, 2657, 1970, 2930}, // #70
+ {12, 2677, 2697, 1834, 2930}, // #71
+ {12, 2713, 2729, 1474, 2930}, // #72
+ {12, 2749, 2769, 2250, 2930}, // #73
+ {12, 2789, 2809, 2458, 2930}, // #74
+ {12, 2829, 2849, 2618, 2930}, // #75
+ {12, 2869, 2889, 3066, 2930}, // #76
+ {12, 2905, 2921, 3330, 2930}, // #77
+ {12, 2941, 2961, 1706, 2930}, // #78
+ {12, 2977, 2993, 2802, 2930}, // #79
+ {12, 3013, 3033, 3770, 2930}, // #80
+ {12, 3053, 3073, 3594, 2930}, // #81
+ {12, 3089, 3105, 2, 2930}, // #82
+ {12, 3121, 3137, 2962, 2930}, // #83
+ {12, 3153, 3169, 290, 2930}, // #84
+ {12, 3189, 3209, 794, 2930}, // #85
+ {12, 3225, 3241, 1058, 2930}, // #86
+ {12, 3261, 3281, 2394, 2930}, // #87
+ {12, 3301, 3321, 138, 2930}, // #88
+ {12, 3341, 3361, 1482, 2930}, // #89
+ {12, 3381, 3401, 570, 2930}, // #90
+ {12, 3417, 3433, 674, 2930}, // #91
+ {12, 3449, 3465, 1282, 2930}, // #92
+ {12, 3481, 3497, 1746, 2930}, // #93
+ {12, 3517, 3537, 1866, 2930}, // #94
+ {12, 3557, 3577, 1978, 2930}, // #95
+ {12, 3593, 3609, 3954, 2930}, // #96
+ {12, 3629, 3649, 2570, 2930}, // #97
+ {12, 3665, 3681, 2754, 2930}, // #98
+ {12, 3697, 3713, 3666, 2930}, // #99
+ {12, 3729, 3745, 34, 2930}, // #100
+ {12, 3761, 3777, 2914, 2930}, // #101
+ {12, 3797, 3817, 1194, 2930}, // #102
+ {12, 3833, 3849, 3202, 2930}, // #103
+ {12, 3869, 3889, 3018, 2930}, // #104
+ {12, 3909, 3929, 202, 2930}, // #105
+ {12, 3949, 3969, 3546, 2930}, // #106
+ {12, 3985, 4001, 3682, 2930}, // #107
+ {12, 4021, 4041, 3466, 2930}, // #108
+ {12, 4061, 4081, 4074, 2930}, // #109
+ {12, 4097, 4113, 306, 2930}, // #110
+ {12, 4133, 4153, 634, 2930}, // #111
+ {12, 4169, 4185, 802, 2930}, // #112
+ {12, 4201, 4217, 962, 2930}, // #113
+ {12, 4237, 4257, 1114, 2930}, // #114
+ {12, 4273, 4289, 1250, 2930}, // #115
+ {12, 4309, 4329, 3898, 2930}, // #116
+ {12, 4349, 4369, 1386, 2930}, // #117
+ {12, 4385, 4401, 1586, 2930}, // #118
+ {12, 4417, 4433, 1730, 2930}, // #119
+ {12, 4453, 4473, 1914, 2930}, // #120
+ {12, 4493, 4513, 1498, 2930}, // #121
+ {12, 4533, 4553, 2138, 2930}, // #122
+ {12, 4569, 4585, 2290, 2930}, // #123
+ {12, 4605, 4625, 2426, 2930}, // #124
+ {12, 4645, 4665, 2666, 2930}, // #125
+ {12, 4681, 4697, 2050, 2930}, // #126
+ {12, 4717, 4737, 2874, 2930}, // #127
+ {12, 4757, 4777, 3018, 2930}, // #128
+ {12, 4797, 4817, 1834, 2930}, // #129
+ {12, 4837, 4857, 3178, 2930}, // #130
+ {12, 4873, 4889, 3314, 2930}, // #131
+ {12, 4905, 4921, 2546, 2930}, // #132
+ {12, 4941, 4961, 3546, 2930}, // #133
+ {12, 4977, 4993, 3682, 2930}, // #134
+ {12, 5013, 5033, 3802, 2930}, // #135
+ {12, 5049, 5065, 3922, 2930}, // #136
+ {12, 5081, 5097, 4018, 2930}, // #137
+ {12, 5117, 5137, 42, 2930}, // #138
+ {12, 5153, 5169, 130, 2930}, // #139
+ {12, 5185, 5201, 242, 2930}, // #140
+};
+static const int stringCollectionCount = 141;
+static const int stringCollectionMaxLen = 51;
+// average comparison length: 12.0922
+// cache-line crosses: 6 (2.1%)
+// alignment histogram:
+// 0xXXX2 = 188 (66.7%) strings, 57 (30.3%) of which same-aligned
+// 0xXXXa = 94 (33.3%) strings, 10 (10.6%) of which same-aligned
+// total = 282 (100%) strings, 67 (23.8%) of which same-aligned
diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp
index fb65f65..88dc40b 100644
--- a/tests/benchmarks/corelib/tools/qstring/main.cpp
+++ b/tests/benchmarks/corelib/tools/qstring/main.cpp
@@ -48,8 +48,15 @@
#define SRCDIR ""
#endif
+#ifdef Q_OS_UNIX
+#include <sys/mman.h>
+#include <unistd.h>
+#endif
+
#include <private/qsimd_p.h>
+#include "data.cpp"
+
class tst_QString: public QObject
{
Q_OBJECT
@@ -73,20 +80,8 @@ void tst_QString::equals() const
}
}
-static ushort databuffer[4096];
-
tst_QString::tst_QString()
{
- // populate databuffer with our seed, each byte 3 times in a row
- // include the NUL!
- static const char seed[] = "AAAAAAAAAEhlbGxvIFdvcmxkIAAAAAA=";
- static const int repeat = 3;
- int pos = 0;
- for (ushort *p = databuffer; p < databuffer + (sizeof(databuffer) / sizeof(databuffer[0])); p += repeat) {
- for (int j = 0; j < repeat; ++p, ++j)
- *p = seed[pos];
- pos = (pos + 1) % sizeof(seed);
- }
}
void tst_QString::equals_data() const
@@ -148,13 +143,15 @@ void tst_QString::equals_data() const
<< QString::fromRawData(ptr + 1, 58) << QString::fromRawData(ptr + 3, 58);
}
-static bool equals2_memcmp_call(ushort *p1, ushort *p2, int len)
+static bool equals2_memcmp_call(const ushort *p1, const ushort *p2, int len)
{
return memcmp(p1, p2, len * 2) == 0;
}
-static bool equals2_bytewise(ushort *p1, ushort *p2, int len)
+static bool equals2_bytewise(const ushort *p1, const ushort *p2, int len)
{
+ if (p1 == p2 || !len)
+ return true;
uchar *b1 = (uchar *)p1;
uchar *b2 = (uchar *)p2;
len *= 2;
@@ -164,17 +161,24 @@ static bool equals2_bytewise(ushort *p1, ushort *p2, int len)
return true;
}
-static bool equals2_shortwise(ushort *p1, ushort *p2, int len)
+static bool __attribute__((optimize("unroll-loops"))) equals2_shortwise(const ushort *p1, const ushort *p2, int len)
{
- register ushort * const end = p1 + len;
- for ( ; p1 != end; ++p1, ++p2)
- if (*p1 != *p2)
+ if (p1 == p2 || !len)
+ return true;
+// for (register int counter; counter < len; ++counter)
+// if (p1[counter] != p2[counter])
+// return false;
+ while (len--) {
+ if (p1[len] != p2[len])
return false;
+ }
return true;
}
-static bool equals2_intwise(ushort *p1, ushort *p2, int length)
+static bool equals2_intwise(const ushort *p1, const ushort *p2, int length)
{
+ if (p1 == p2 || !length)
+ return true;
register union {
const quint16 *w;
const quint32 *d;
@@ -219,71 +223,204 @@ static bool equals2_intwise(ushort *p1, ushort *p2, int length)
return true;
}
+static inline bool equals2_short_tail(const ushort *p1, const ushort *p2, int len)
+{
+ if (len) {
+ if (*p1 != *p2)
+ return false;
+ if (--len) {
+ if (p1[1] != p2[1])
+ return false;
+ if (--len) {
+ if (p1[2] != p2[2])
+ return false;
+ if (--len) {
+ if (p1[3] != p2[3])
+ return false;
+ if (--len) {
+ if (p1[4] != p2[4])
+ return false;
+ if (--len) {
+ if (p1[5] != p2[5])
+ return false;
+ if (--len) {
+ if (p1[6] != p2[6])
+ return false;
+ return p1[7] == p2[7];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+#pragma GCC optimize("no-unroll-loops")
#ifdef __SSE2__
-static bool equals2_sse2(ushort *p1, ushort *p2, int len)
+static bool equals2_sse2_aligned(const ushort *p1, const ushort *p2, int len)
{
- if (len > 8) {
+ if (len >= 8) {
+ qptrdiff counter = 0;
while (len > 8) {
- __m128i q1 = _mm_loadu_si128((__m128i *)p1);
- __m128i q2 = _mm_loadu_si128((__m128i *)p2);
+ __m128i q1 = _mm_load_si128((__m128i *)(p1 + counter));
+ __m128i q2 = _mm_load_si128((__m128i *)(p2 + counter));
+ __m128i cmp = _mm_cmpeq_epi16(q1, q2);
+ if (ushort(_mm_movemask_epi8(cmp)) != ushort(0xffff))
+ return false;
+
+ len -= 8;
+ counter += 8;
+ }
+ p1 += counter;
+ p2 += counter;
+ }
+
+ return equals2_short_tail(p1, p2, len);
+}
+
+static bool __attribute__((optimize("no-unroll-loops"))) equals2_sse2(const ushort *p1, const ushort *p2, int len)
+{
+ if (p1 == p2 || !len)
+ return true;
+
+ if (len >= 8) {
+ qptrdiff counter = 0;
+ while (len >= 8) {
+ __m128i q1 = _mm_loadu_si128((__m128i *)(p1 + counter));
+ __m128i q2 = _mm_loadu_si128((__m128i *)(p2 + counter));
__m128i cmp = _mm_cmpeq_epi16(q1, q2);
if (ushort(_mm_movemask_epi8(cmp)) != 0xffff)
return false;
len -= 8;
- p1 += 8;
- p2 += 8;
+ counter += 8;
}
+ p1 += counter;
+ p2 += counter;
}
- return equals2_shortwise(p1, p2, len);
+ return equals2_short_tail(p1, p2, len);
}
-static inline
-#ifdef Q_CC_GNU
-__attribute__((always_inline))
-#endif
-bool prolog_align(ushort *&p1, ushort *&p2, int &len)
+//static bool equals2_sse2(const ushort *p1, const ushort *p2, int len)
+//{
+// register int val1 = quintptr(p1) & 0xf;
+// register int val2 = quintptr(p2) & 0xf;
+// if (false && val1 + val2 == 0)
+// return equals2_sse2_aligned(p1, p2, len);
+// else
+// return equals2_sse2_unaligned(p1, p2, len);
+//}
+
+static bool equals2_sse2_aligning(const ushort *p1, const ushort *p2, int len)
{
- const ushort *end = (ushort*) ((quintptr(p1) + 15) & ~15);
- if (end > p1 + len)
- end = p1 + len;
- for ( ; p1 != end; ++p1, ++p2, --len)
- if (*p1 != *p2)
+ if (len < 8)
+ return equals2_short_tail(p1, p2, len);
+
+ qptrdiff counter = 0;
+
+ // which one is easier to align, p1 or p2 ?
+ register int val1 = quintptr(p1) & 0xf;
+ register int val2 = quintptr(p2) & 0xf;
+ if (val1 && val2) {
+#if 0
+ // we'll align the one which requires the least number of steps
+ if (val1 > val2) {
+ qSwap(p1, p2);
+ val1 = val2;
+ }
+
+ // val1 contains the number of bytes past the 16-aligned mark
+ // we must read 16-val1 bytes to align
+ val1 = 16 - val1;
+ if (val1 & 0x2) {
+ if (*p1 != *p2)
+ return false;
+ --len;
+ ++counter;
+ }
+ while (val1 & 12) {
+ if (*(uint*)p1 != *(uint*)p2)
+ return false;
+ --len;
+ counter += 2;
+ val1 -= 4;
+ }
+#else
+ // we'll align the one closest to the 16-byte mark
+ if (val1 > val2) {
+ qSwap(p1, p2);
+ val1 = val2;
+ }
+
+ // we're reading val1 bytes too many
+ __m128i q2 = _mm_loadu_si128((__m128i *)(p2 - val1/2));
+ __m128i cmp = _mm_cmpeq_epi16(*(__m128i *)(p1 - val1/2), q2);
+ if (short(_mm_movemask_epi8(cmp)) >> val1 != short(-1))
return false;
- return true;
+
+ counter = 8 - val1/2;
+ len -= 8 - val1/2;
+#endif
+ } else if (!val2) {
+ // p2 is already aligned
+ qSwap(p1, p2);
+ }
+
+ // p1 is aligned
+
+ while (len >= 8) {
+ __m128i q1 = _mm_load_si128((__m128i *)(p1 + counter));
+ __m128i q2 = _mm_loadu_si128((__m128i *)(p2 + counter));
+ __m128i cmp = _mm_cmpeq_epi16(q1, q2);
+ if (ushort(_mm_movemask_epi8(cmp)) != ushort(0xffff))
+ return false;
+
+ len -= 8;
+ counter += 8;
+ }
+
+ // tail
+ return equals2_short_tail(p1 + counter, p2 + counter, len);
}
-static bool equals2_sse2_aligning(ushort *p1, ushort *p2, int len)
+#ifdef __SSE3__
+static bool __attribute__((optimize("no-unroll-loops"))) equals2_sse3(const ushort *p1, const ushort *p2, int len)
{
- if (len > 8) {
- if (!prolog_align(p1, p2, len))
- return false;
- while (len > 8) {
- __m128i q1 = _mm_load_si128((__m128i *)p1);
- __m128i q2 = _mm_loadu_si128((__m128i *)p2);
+ if (p1 == p2 || !len)
+ return true;
+
+ if (len >= 8) {
+ qptrdiff counter = 0;
+ while (len >= 8) {
+ __m128i q1 = _mm_lddqu_si128((__m128i *)(p1 + counter));
+ __m128i q2 = _mm_lddqu_si128((__m128i *)(p2 + counter));
__m128i cmp = _mm_cmpeq_epi16(q1, q2);
if (ushort(_mm_movemask_epi8(cmp)) != 0xffff)
return false;
len -= 8;
- p1 += 8;
- p2 += 8;
+ counter += 8;
}
+ p1 += counter;
+ p2 += counter;
}
- return equals2_shortwise(p1, p2, len);
+ return equals2_short_tail(p1, p2, len);
}
-template<int N> static inline bool equals2_ssse3_alignr(__m128i *m1, __m128i *m2, int len)
+#ifdef __SSSE3__
+template<int N> static __attribute__((optimize("unroll-loops"))) inline bool equals2_ssse3_alignr(__m128i *m1, __m128i *m2, int len)
{
__m128i lower = _mm_load_si128(m1);
- while (len > 8) {
+ while (len >= 8) {
__m128i upper = _mm_load_si128(m1 + 1);
__m128i correct;
correct = _mm_alignr_epi8(upper, lower, N);
- __m128i q2 = _mm_loadu_si128(m2);
+ __m128i q2 = _mm_lddqu_si128(m2);
__m128i cmp = _mm_cmpeq_epi16(correct, q2);
if (ushort(_mm_movemask_epi8(cmp)) != 0xffff)
return false;
@@ -295,13 +432,13 @@ template<int N> static inline bool equals2_ssse3_alignr(__m128i *m1, __m128i *m2
}
// tail
- return len == 0 || equals2_shortwise((ushort *)m1 + N / 2, (ushort*)m2, len);
+ return len == 0 || equals2_short_tail((const ushort *)m1 + N / 2, (const ushort*)m2, len);
}
-static inline bool equals2_ssse3_aligned(__m128i *m1, __m128i *m2, int len)
+static inline __attribute__((optimize("unroll-loops"))) bool equals2_ssse3_aligned(__m128i *m1, __m128i *m2, int len)
{
- while (len > 8) {
- __m128i q2 = _mm_loadu_si128(m2);
+ while (len >= 8) {
+ __m128i q2 = _mm_lddqu_si128(m2);
__m128i cmp = _mm_cmpeq_epi16(*m1, q2);
if (ushort(_mm_movemask_epi8(cmp)) != 0xffff)
return false;
@@ -310,30 +447,30 @@ static inline bool equals2_ssse3_aligned(__m128i *m1, __m128i *m2, int len)
++m1;
++m2;
}
- return len == 0 || equals2_shortwise((ushort *)m1, (ushort *)m2, len);
+ return len == 0 || equals2_short_tail((const ushort *)m1, (const ushort *)m2, len);
}
-//#ifdef __SSSE3__
-static bool equals2_ssse3(ushort *p1, ushort *p2, int len)
+static bool equals2_ssse3(const ushort *p1, const ushort *p2, int len)
{
// p1 & 0xf can be:
// 0, 2, 4, 6, 8, 10, 12, 14
// If it's 0, we're aligned
// If it's not, then we're interested in the 16 - (p1 & 0xf) bytes only
- if (len > 8) {
+ if (len >= 8) {
// find the last aligned position below the p1 memory
__m128i *m1 = (__m128i *)(quintptr(p1) & ~0xf);
__m128i *m2 = (__m128i *)p2;
- uchar diff = quintptr(p1) - quintptr(m1);
+ qptrdiff diff = quintptr(p1) - quintptr(m1);
// diff contains the number of extra bytes
+ if (diff == 10)
+ return equals2_ssse3_alignr<10>(m1, m2, len);
+ else if (diff == 2)
+ return equals2_ssse3_alignr<2>(m1, m2, len);
if (diff < 8) {
if (diff < 4) {
- if (diff == 0)
- return equals2_ssse3_aligned(m1, m2, len);
- else // diff == 2
- return equals2_ssse3_alignr<2>(m1, m2, len);
+ return equals2_ssse3_aligned(m1, m2, len);
} else {
if (diff == 4)
return equals2_ssse3_alignr<4>(m1, m2, len);
@@ -342,10 +479,7 @@ static bool equals2_ssse3(ushort *p1, ushort *p2, int len)
}
} else {
if (diff < 12) {
- if (diff == 8)
- return equals2_ssse3_alignr<8>(m1, m2, len);
- else // diff == 10
- return equals2_ssse3_alignr<10>(m1, m2, len);
+ return equals2_ssse3_alignr<8>(m1, m2, len);
} else {
if (diff == 12)
return equals2_ssse3_alignr<12>(m1, m2, len);
@@ -353,34 +487,99 @@ static bool equals2_ssse3(ushort *p1, ushort *p2, int len)
return equals2_ssse3_alignr<14>(m1, m2, len);
}
}
+ }
+
+ // tail
+ return equals2_short_tail(p1, p2, len);
+}
+
+template<int N> static inline bool equals2_ssse3_aligning_alignr(__m128i *m1, __m128i *m2, int len)
+{
+ __m128i lower = _mm_load_si128(m1);
+ while (len >= 8) {
+ __m128i upper = _mm_load_si128(m1 + 1);
+ __m128i correct;
+ correct = _mm_alignr_epi8(upper, lower, N);
+
+ __m128i cmp = _mm_cmpeq_epi16(correct, *m2);
+ if (ushort(_mm_movemask_epi8(cmp)) != 0xffff)
+ return false;
-// switch (diff) {
-// case 0:
-// return equals2_ssse3_aligned(m1, m2, len);
-// case 2:
-// return equals2_ssse3_alignr<2>(m1, m2, len);
-// case 4:
-// return equals2_ssse3_alignr<4>(m1, m2, len);
-// case 6:
-// return equals2_ssse3_alignr<6>(m1, m2, len);
-// case 8:
-// return equals2_ssse3_alignr<8>(m1, m2, len);
-// case 10:
-// return equals2_ssse3_alignr<10>(m1, m2, len);
-// case 12:
-// return equals2_ssse3_alignr<12>(m1, m2, len);
-// case 14:
-// return equals2_ssse3_alignr<14>(m1, m2, len);
-// }
+ len -= 8;
+ ++m2;
+ ++m1;
+ lower = upper;
}
// tail
- return equals2_shortwise(p1, p2, len);
+ return len == 0 || equals2_short_tail((const ushort *)m1 + N / 2, (const ushort*)m2, len);
}
-//#endif
-//#ifdef __SSE4_1__
-static bool equals2_sse4(ushort *p1, ushort *p2, int len)
+static bool equals2_ssse3_aligning(const ushort *p1, const ushort *p2, int len)
+{
+ if (len < 8)
+ return equals2_short_tail(p1, p2, len);
+ qptrdiff counter = 0;
+
+ // which one is easier to align, p1 or p2 ?
+ {
+ register int val1 = quintptr(p1) & 0xf;
+ register int val2 = quintptr(p2) & 0xf;
+ if (val1 && val2) {
+ // we'll align the one closest to the 16-byte mark
+ if (val1 < val2) {
+ qSwap(p1, p2);
+ val2 = val1;
+ }
+
+ // we're reading val1 bytes too many
+ __m128i q1 = _mm_lddqu_si128((__m128i *)(p1 - val2/2));
+ __m128i cmp = _mm_cmpeq_epi16(q1, *(__m128i *)(p2 - val2/2));
+ if (short(_mm_movemask_epi8(cmp)) >> val1 != short(-1))
+ return false;
+
+ counter = 8 - val2/2;
+ len -= 8 - val2/2;
+ } else if (!val1) {
+ // p1 is already aligned
+ qSwap(p1, p2);
+ }
+ }
+
+ // p2 is aligned now
+ // we want to use palignr in the mis-alignment of p1
+ __m128i *m1 = (__m128i *)(quintptr(p1 + counter) & ~0xf);
+ __m128i *m2 = (__m128i *)(p2 + counter);
+ register int val1 = quintptr(p1 + counter) - quintptr(m1);
+
+ // val1 contains the number of extra bytes
+ if (val1 == 8)
+ return equals2_ssse3_aligning_alignr<8>(m1, m2, len);
+ if (val1 == 0)
+ return equals2_sse2_aligned(p1 + counter, p2 + counter, len);
+ if (val1 < 8) {
+ if (val1 < 4) {
+ return equals2_ssse3_aligning_alignr<2>(m1, m2, len);
+ } else {
+ if (val1 == 4)
+ return equals2_ssse3_aligning_alignr<4>(m1, m2, len);
+ else // diff == 6
+ return equals2_ssse3_aligning_alignr<6>(m1, m2, len);
+ }
+ } else {
+ if (val1 < 12) {
+ return equals2_ssse3_aligning_alignr<10>(m1, m2, len);
+ } else {
+ if (val1 == 12)
+ return equals2_ssse3_aligning_alignr<12>(m1, m2, len);
+ else // diff == 14
+ return equals2_ssse3_aligning_alignr<14>(m1, m2, len);
+ }
+ }
+}
+
+#ifdef __SSE4_1__
+static bool equals2_sse4(const ushort *p1, const ushort *p2, int len)
{
// We use the pcmpestrm instruction searching for differences (negative polarity)
// it will reset CF if it's all equal
@@ -390,36 +589,150 @@ static bool equals2_sse4(ushort *p1, ushort *p2, int len)
// difference found: CF = 1
// all equal, not finished: CF = ZF = SF = 0
// all equal, finished: CF = 0, ZF = SF = 1
+ // We use the JA instruction that jumps if ZF = 0 and CF = 0
+ if (p1 == p2 || !len)
+ return true;
+
+ // This function may read some bytes past the end of p1 or p2
+ // It is safe to do that, as long as those extra bytes (beyond p1+len and p2+len)
+ // are on the same page as the last valid byte.
+ // If len is a multiple of 8, we'll never load invalid bytes.
+ if (len & 7) {
+ // The last load would load (len & ~7) valid bytes and (8 - (len & ~7)) invalid bytes.
+ // So we can't do the last load if any of those bytes is in a different
+ // page. That is, if:
+ // pX + len is on a different page from pX + (len & ~7) + 8
+ //
+ // that is, if second-to-last load ended up less than 16 bytes from the page end:
+ // pX + (len & ~7) is the last ushort read in the second-to-last load
+ if (len < 8)
+ return equals2_short_tail(p1, p2, len);
+ if ((quintptr(p1 + (len & ~7)) & 0xfff) > 0xff0 ||
+ (quintptr(p2 + (len & ~7)) & 0xfff) > 0xff0) {
+
+ // yes, so we mustn't do the final 128-bit load
+ bool result;
+ asm (
+ "sub %[p1], %[p2]\n\t"
+ "sub $16, %[p1]\n\t"
+ "add $8, %[len]\n\t"
+
+ // main loop:
+ "0:\n\t"
+ "add $16, %[p1]\n\t"
+ "sub $8, %[len]\n\t"
+ "jz 1f\n\t"
+ "lddqu (%[p1]), %%xmm0\n\t"
+ "mov %[len], %%edx\n\t"
+ "pcmpestri %[mode], (%[p2],%[p1]), %%xmm0\n\t"
+
+ "jna 1f\n\t"
+ "add $16, %[p1]\n\t"
+ "sub $8, %[len]\n\t"
+ "jz 1f\n\t"
+ "lddqu (%[p1]), %%xmm0\n\t"
+ "mov %[len], %%edx\n\t"
+ "pcmpestri %[mode], (%[p2],%[p1]), %%xmm0\n\t"
+
+ "ja 0b\n\t"
+ "1:\n\t"
+ "setnc %[result]\n\t"
+ : [result] "=a" (result),
+ [p1] "+r" (p1),
+ [p2] "+r" (p2)
+ : [len] "0" (len & ~7),
+ [mode] "i" (_SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY)
+ : "%edx", "%ecx", "%xmm0"
+ );
+ return result && equals2_short_tail(p1, (const ushort *)(quintptr(p1) + quintptr(p2)), len & 7);
+ }
+ }
+
+// const qptrdiff disp = p2 - p1;
+// p1 -= 8;
+// len += 8;
+// while (true) {
+// enum { Mode = _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY };
+
+// p1 += 8;
+// len -= 8;
+// if (!len)
+// return true;
+
+// __m128i q1 = _mm_lddqu_si128((__m128i *)(p1 + disp));
+// __m128i *m2 = (__m128i *)p1;
+
+// bool cmp_a = _mm_cmpestra(q1, len, *m2, len, Mode);
+// if (cmp_a)
+// continue;
+// return !_mm_cmpestrc(q1, len, *m2, len, Mode);
+// }
+// return true;
bool result;
asm (
- "movd %%ebx, %%xmm1\n\t"
"sub %[p1], %[p2]\n\t"
- "mov %[p1], %%ebx\n\t"
- "sub $16, %%ebx\n\t"
+ "sub $16, %[p1]\n\t"
"add $8, %[len]\n\t"
- "0:\n\t"
- "add $16, %%ebx\n\t"
+
+ "0:\n\t"
+ "add $16, %[p1]\n\t"
"sub $8, %[len]\n\t"
- "movdqu (%%ebx), %%xmm0\n\t"
+ "jz 1f\n\t"
+ "lddqu (%[p2],%[p1]), %%xmm0\n\t"
"mov %[len], %%edx\n\t"
- "pcmpestrm %[mode], (%[p2],%%ebx), %%xmm0\n\t"
+ "pcmpestri %[mode], (%[p1]), %%xmm0\n\t"
+
+ "jna 1f\n\t"
+ "add $16, %[p1]\n\t"
+ "sub $8, %[len]\n\t"
+ "jz 1f\n\t"
+ "lddqu (%[p2],%[p1]), %%xmm0\n\t"
+ "mov %[len], %%edx\n\t"
+ "pcmpestri %[mode], (%[p1]), %%xmm0\n\t"
+
"ja 0b\n\t"
- "1:\n\t"
- "mov $0, %%eax\n\t"
- "setnc %%al\n\t"
- "movd %%xmm1, %%ebx\n\t"
+
+ "1:\n\t"
+ "setnc %[result]\n\t"
: [result] "=a" (result)
: [len] "0" (len),
- [p1] "d" (p1),
+ [p1] "r" (p1),
[p2] "r" (p2),
- [mode] "K" (_SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY)
- : "%xmm0", "%xmm1"
+ [mode] "i" (_SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY)
+ : "%edx", "%ecx", "%xmm0"
);
return result;
}
-//#endif
+
+#endif
+#endif
+#endif
#endif
+typedef bool (* FuncPtr)(const ushort *, const ushort *, int);
+static const FuncPtr func[] = {
+ equals2_memcmp_call, // 0
+ equals2_bytewise, // 1
+ equals2_shortwise, // 1
+ equals2_intwise, // 3
+#ifdef __SSE2__
+ equals2_sse2, // 4
+ equals2_sse2_aligning, // 5
+#ifdef __SSE3__
+ equals2_sse3, // 6
+#ifdef __SSSE3__
+ equals2_ssse3, // 7
+ equals2_ssse3, // 8
+#ifdef __SSE4_1__
+ equals2_sse4, // 9
+#endif
+#endif
+#endif
+#endif
+ 0
+};
+static const int functionCount = sizeof(func)/sizeof(func[0]) - 1;
+
void tst_QString::equals2_data() const
{
QTest::addColumn<int>("algorithm");
@@ -431,108 +744,94 @@ void tst_QString::equals2_data() const
#ifdef __SSE2__
QTest::newRow("sse2") << 4;
QTest::newRow("sse2_aligning") << 5;
+#ifdef __SSE3__
+ QTest::newRow("sse3") << 6;
#ifdef __SSSE3__
- QTest::newRow("ssse3") << 6;
+ QTest::newRow("ssse3") << 7;
+ QTest::newRow("ssse3_aligning") << 8;
#ifdef __SSE4_1__
- QTest::newRow("sse4.2") << 7;
+ QTest::newRow("sse4.2") << 9;
+#endif
#endif
#endif
#endif
}
-void tst_QString::equals2() const
+static void __attribute__((noinline)) equals2_selftest()
{
- static const short positions[] = {
- 190, 1719, 2149, 1752,
- 158, 244, 365, 1117,
- 254, 265, 1047, 1785,
- 1435, 552, 1476, 2030,
- // 16
- 421, 1840, 2209, 232,
- 1389, 907, 1500, 1479,
- 1152, 541, 655, 1960,
- 1642, 299, 740, 1995,
- // 32
- 1946, 1407, 1272, 1946,
- 1459, 1851, 1717, 1484,
- 1761, 1630, 1377, 1675,
- 629, 341, 661, 244
- // 48
- };
- // the length list must not contain 0
- static const int lens[] = {
- 11, // 0
- 40,
- 28,
- 38,
- 9,
- 52, // 5
- 48,
- 38,
- 29,
- 7,
- 2, // 10
- 49,
- 41,
- 5,
- 20,
- 62 // 15
+#ifdef Q_OS_UNIX
+ const long pagesize = sysconf(_SC_PAGESIZE);
+ void *page1, *page3;
+ ushort *page2;
+ page1 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ page2 = (ushort *)mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
+ page3 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ Q_ASSERT(quintptr(page2) == quintptr(page1) + pagesize || quintptr(page2) == quintptr(page1) - pagesize);
+ Q_ASSERT(quintptr(page3) == quintptr(page2) + pagesize || quintptr(page3) == quintptr(page2) - pagesize);
+ munmap(page1, pagesize);
+ munmap(page3, pagesize);
+
+ // populate our page
+ for (uint i = 0; i < pagesize / sizeof(long long); ++i)
+ ((long long *)page2)[i] = Q_INT64_C(0x0041004100410041);
+
+ // the following should crash:
+ //page2[-1] = 0xdead;
+ //page2[pagesize / sizeof(ushort) + 1] = 0xbeef;
+
+ static const ushort needle[] = {
+ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
+ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
+ 0x41
};
- typedef bool (* FuncPtr)(ushort *, ushort *, int);
- static const FuncPtr func[] = {
- equals2_memcmp_call, // 0
- equals2_bytewise, // 1
- equals2_shortwise, // 1
- equals2_intwise, // 3
-#ifdef __SSE2__
- equals2_sse2, // 4
- equals2_sse2_aligning, // 5
-#ifdef __SSSE3__
- equals2_ssse3, // 6
-#ifdef __SSE4_1__
- equals2_sse4, // 7
-#endif
-#endif
+ for (int algo = 0; algo < functionCount; ++algo) {
+ // boundary condition test:
+ for (int i = 0; i < 8; ++i) {
+ (func[algo])(page2 + i, needle, sizeof needle / 2);
+ (func[algo])(page2 - i - 1 - sizeof(needle)/2 + pagesize/2, needle, sizeof needle/2);
+ }
+ }
+
+ munmap(page2, pagesize);
#endif
- 0
- };
+ for (int algo = 0; algo < functionCount; ++algo) {
+ for (int i = 0; i < stringCollectionCount; ++i) {
+ const ushort *p1 = stringCollectionData + stringCollection[i].offset1;
+ const ushort *p2 = stringCollectionData + stringCollection[i].offset2;
+ bool expected = memcmp(p1, p2, stringCollection[i].len * 2) == 0;
+
+ bool result = (func[algo])(p1, p2, stringCollection[i].len);
+ if (expected != result)
+ qWarning().nospace()
+ << "algo=" << algo
+ << " i=" << i
+ << " failed (" << result << "!=" << expected
+ << "); strings were "
+ << QByteArray((char*)p1, stringCollection[i].len).toHex()
+ << " and "
+ << QByteArray((char*)p2, stringCollection[i].len).toHex();
+ }
+ }
+}
+
+void tst_QString::equals2() const
+{
QFETCH(int, algorithm);
if (algorithm == -1) {
- for (uint pos1 = 0; pos1 < sizeof positions / sizeof positions[0]; ++pos1)
- for (uint pos2 = 0; pos2 < (sizeof positions / sizeof positions[0]) - 32; ++pos2)
- for (uint len = 0; len < sizeof lens / sizeof lens[0]; ++len) {
- ushort *p1 = databuffer + positions[pos1];
- ushort *p2 = databuffer + positions[pos2];
- bool expected = memcmp(p1, p2, lens[len] * 2) == 0;
-
- for (uint algo = 0; algo < -1 + (sizeof func / sizeof func[0]); ++algo) {
- bool result = (func[algo])(p1, p2, lens[len]);
- if (expected != result)
- qWarning().nospace()
- << "algo=" << algo
- << " pos1=" << positions[pos1]
- << " pos2=" << positions[pos2]
- << " len=" << lens[len]
- << " failed (" << result << "!=" << expected
- << "); strings were "
- << QByteArray((char*)p1, lens[len]).toHex()
- << " and "
- << QByteArray((char*)p2, lens[len]).toHex();
- }
-
- }
+ equals2_selftest();
return;
}
QBENCHMARK {
- for (uint pos1 = 0; pos1 < sizeof positions / sizeof positions[0]; ++pos1)
- for (uint pos2 = 0; pos2 < (sizeof positions / sizeof positions[0]) - 32; ++pos2)
- for (uint len = 0; len < sizeof lens / sizeof lens[0]; ++len) {
- bool result = (func[algorithm])(databuffer + positions[pos1], databuffer + positions[pos2], lens[len]);
- Q_UNUSED(result);
- }
+ for (int i = 0; i < stringCollectionCount; ++i) {
+ const ushort *p1 = stringCollectionData + stringCollection[i].offset1;
+ const ushort *p2 = stringCollectionData + stringCollection[i].offset2;
+ bool result = (func[algorithm])(p1, p2, stringCollection[i].len);
+ Q_UNUSED(result);
+ }
}
}