回答編集履歴

4

modify

2016/03/26 12:07

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -212,7 +212,7 @@
212
212
 
213
213
  - `String#startsWith`は,V8においてはあまり最適化されておらず,`String#indexOf`よりも低速.一方SpiderMonkeyにおいては最適化されており,安定して高速.
214
214
 
215
- - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,**「マッチしない長い文字列」において著しく動作が遅くなる**傾向にある.
215
+ - `String#indexOf`は,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,**「マッチしない長い文字列」において著しく動作が遅くなる**傾向にある.
216
216
 
217
217
 
218
218
 

3

update

2016/03/26 12:07

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -212,8 +212,8 @@
212
212
 
213
213
  - `String#startsWith`は,V8においてはあまり最適化されておらず,`String#indexOf`よりも低速.一方SpiderMonkeyにおいては最適化されており,安定して高速.
214
214
 
215
- - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,「マッチしない長い文字列」において著しく動作が遅くなる傾向にある.
215
+ - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,**「マッチしない長い文字列」において著しく動作が遅くなる**傾向にある.
216
-
217
-
218
-
216
+
217
+
218
+
219
- V8の`String#indexOf`が「マッチしない長い文字列」に対して高速な理由が気になりますね.右辺の値を先に見て,それ以上無駄な走査を行わないようにする…という高度な最適化でもやってるんでしょうか.
219
+ V8の`String#indexOf`が**「マッチしない長い文字列」に対して高速**な理由が気になりますね.右辺の値を先に見て,それ以上無駄な走査を行わないようにする…という高度な最適化でもやってるんでしょうか.

2

考察

2016/03/26 11:58

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -1,3 +1,7 @@
1
+ # コード
2
+
3
+
4
+
1
5
  ```js
2
6
 
3
7
  'use strict';
@@ -6,112 +10,210 @@
6
10
 
7
11
  [
8
12
 
9
- '※abc',
13
+ ['※abc', 'マッチする短い文字列'],
10
-
14
+
11
- 'abc',
15
+ ['abc', 'マッチしない短い文字列'],
12
-
16
+
13
- '※' + new Array(10000).join('a'),
17
+ ['※' + new Array(10000).join('a'), 'マッチする長い文字列'],
14
-
18
+
15
- '' + new Array(10000).join('a'),
19
+ ['' + new Array(10000).join('a'), 'マッチしない長い文字列'],
16
-
20
+
17
- ].map(function (str, index) {
21
+ ].map(function (item) {
22
+
23
+ var i;
24
+
25
+ var str = item[0];
26
+
27
+
28
+
29
+ console.time('indexOf-' + item[1]);
30
+
31
+ for (i = 0; i < 10000000; ++i) {
32
+
33
+ str.indexOf('※') === 0;
34
+
35
+ }
36
+
37
+ console.timeEnd('indexOf-' + item[1]);
38
+
39
+
40
+
41
+ console.time('RegExp-' + item[1]);
42
+
43
+ for (i = 0; i < 10000000; ++i) {
44
+
45
+ str.match(/^※/);
46
+
47
+ }
48
+
49
+ console.timeEnd('RegExp-' + item[1]);
50
+
51
+
52
+
53
+ console.time('startsWith-' + item[1]);
54
+
55
+ for (i = 0; i < 10000000; ++i) {
56
+
57
+ str.startsWith('※');
58
+
59
+ }
60
+
61
+ console.timeEnd('startsWith-' + item[1]);
18
62
 
19
63
 
20
64
 
21
- var i;
22
-
23
-
24
-
25
- console.time('indexOf ' + index);
26
-
27
- for (i = 0; i < 10000000; ++i) {
28
-
29
- str.indexOf('※') === 0;
30
-
31
- }
32
-
33
- console.timeEnd('indexOf ' + index);
34
-
35
-
36
-
37
- console.time('RegExp ' + index);
65
+ console.log();
38
-
39
- for (i = 0; i < 10000000; ++i) {
40
-
41
- str.match(/^※/);
42
-
43
- }
44
-
45
- console.timeEnd('RegExp ' + index);
46
-
47
-
48
-
49
- console.time('startsWith ' + index);
50
-
51
- for (i = 0; i < 10000000; ++i) {
52
-
53
- str.startsWith('※');
54
-
55
- }
56
-
57
- console.timeEnd('startsWith ' + index);
58
66
 
59
67
 
60
68
 
61
- console.log();
62
-
63
-
64
-
65
69
  });
66
70
 
67
71
  ```
68
72
 
69
73
 
70
74
 
71
- ```
72
-
73
- indexOf 0: 422.819ms
74
-
75
- RegExp 0: 1139.455ms
76
-
77
- startsWith 0: 656.991ms
78
-
79
-
80
-
81
- indexOf 1: 465.062ms
82
-
83
- RegExp 1: 377.014ms
84
-
85
- startsWith 1: 672.477ms
86
-
87
-
88
-
89
- indexOf 2: 469.188ms
90
-
91
- RegExp 2: 1238.448ms
92
-
93
- startsWith 2: 646.982ms
94
-
95
-
96
-
97
- indexOf 3: 458.261ms
98
-
99
- RegExp 3: 388.297ms
100
-
101
- startsWith 3: 664.676ms
102
-
103
- ```
104
-
105
-
106
-
107
- `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかっているからでしょう.
108
-
109
-
110
-
111
- ```
112
-
113
- > '※abc'.match(/※/)
114
-
115
- [ '※', index: 0, input: '※abc' ]
116
-
117
- ```
75
+ # 結果
76
+
77
+
78
+
79
+ ## V8系
80
+
81
+
82
+
83
+ ###### Node.js
84
+
85
+
86
+
87
+ ```
88
+
89
+ indexOf-マッチする短い文字列: 451.954ms
90
+
91
+ RegExp-マッチする短い文字列: 1168.502ms
92
+
93
+ startsWith-マッチする短い文字列: 656.937ms
94
+
95
+
96
+
97
+ indexOf-マッチしない短い文字列: 451.098ms
98
+
99
+ RegExp-マッチしない短い文字列: 377.314ms
100
+
101
+ startsWith-マッチしない短い文字列: 673.922ms
102
+
103
+
104
+
105
+ indexOf-マッチする長い文字列: 458.273ms
106
+
107
+ RegExp-マッチする長い文字列: 1188.736ms
108
+
109
+ startsWith-マッチする長い文字列: 678.872ms
110
+
111
+
112
+
113
+ indexOf-マッチしない長い文字列: 442.082ms
114
+
115
+ RegExp-マッチしない長い文字列: 377.708ms
116
+
117
+ startsWith-マッチしない長い文字列: 649.069ms
118
+
119
+ ```
120
+
121
+
122
+
123
+ ###### Chrome
124
+
125
+
126
+
127
+ ```
128
+
129
+ indexOf-マッチする短い文字列: 676.688ms
130
+
131
+ RegExp-マッチする短い文字列: 1360.670ms
132
+
133
+ startsWith-マッチする短い文字列: 1462.866ms
134
+
135
+
136
+
137
+ indexOf-マッチしない短い文字列: 541.262ms
138
+
139
+ RegExp-マッチしない短い文字列: 617.367ms
140
+
141
+ startsWith-マッチしない短い文字列: 851.028ms
142
+
143
+
144
+
145
+ indexOf-マッチする長い文字列: 636.199ms
146
+
147
+ RegExp-マッチする長い文字列: 1344.160ms
148
+
149
+ startsWith-マッチする長い文字列: 1424.883ms
150
+
151
+
152
+
153
+ indexOf-マッチしない長い文字列: 506.433ms
154
+
155
+ RegExp-マッチしない長い文字列: 517.285ms
156
+
157
+ startsWith-マッチしない長い文字列: 780.458ms
158
+
159
+ ```
160
+
161
+
162
+
163
+ ## SpiderMonkey系
164
+
165
+
166
+
167
+ ###### Firefox
168
+
169
+
170
+
171
+ ```
172
+
173
+ indexOf-マッチする短い文字列: 284.28ms
174
+
175
+ RegExp-マッチする短い文字列: 3639.21ms
176
+
177
+ startsWith-マッチする短い文字列: 265.69ms
178
+
179
+
180
+
181
+ indexOf-マッチしない短い文字列: 276.58ms
182
+
183
+ RegExp-マッチしない短い文字列: 1038.85ms
184
+
185
+ startsWith-マッチしない短い文字列: 285.4ms
186
+
187
+
188
+
189
+ indexOf-マッチする長い文字列: 294.38ms
190
+
191
+ RegExp-マッチする長い文字列: 3774.39ms
192
+
193
+ startsWith-マッチする長い文字列: 303.2ms
194
+
195
+
196
+
197
+ indexOf-マッチしない長い文字列: 26592.07ms
198
+
199
+ RegExp-マッチしない長い文字列: 1386.18ms
200
+
201
+ startsWith-マッチしない長い文字列: 285.8ms
202
+
203
+ ```
204
+
205
+
206
+
207
+ # 考察
208
+
209
+
210
+
211
+ - `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかるから.
212
+
213
+ - `String#startsWith`は,V8においてはあまり最適化されておらず,`String#indexOf`よりも低速.一方SpiderMonkeyにおいては最適化されており,安定して高速.
214
+
215
+ - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,「マッチしない長い文字列」において著しく動作が遅くなる傾向にある.
216
+
217
+
218
+
219
+ V8の`String#indexOf`が「マッチしない長い文字列」に対して高速な理由が気になりますね.右辺の値を先に見て,それ以上無駄な走査を行わないようにする…という高度な最適化でもやってるんでしょうか.

1

解説

2016/03/26 11:57

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -101,3 +101,17 @@
101
101
  startsWith 3: 664.676ms
102
102
 
103
103
  ```
104
+
105
+
106
+
107
+ `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかっているからでしょう.
108
+
109
+
110
+
111
+ ```
112
+
113
+ > '※abc'.match(/※/)
114
+
115
+ [ '※', index: 0, input: '※abc' ]
116
+
117
+ ```