teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

modify

2016/03/26 12:07

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -105,6 +105,6 @@
105
105
 
106
106
  - `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかるから.
107
107
  - `String#startsWith`は,V8においてはあまり最適化されておらず,`String#indexOf`よりも低速.一方SpiderMonkeyにおいては最適化されており,安定して高速.
108
- - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,**「マッチしない長い文字列」において著しく動作が遅くなる**傾向にある.
108
+ - `String#indexOf`は,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,**「マッチしない長い文字列」において著しく動作が遅くなる**傾向にある.
109
109
 
110
110
  V8の`String#indexOf`が**「マッチしない長い文字列」に対して高速**な理由が気になりますね.右辺の値を先に見て,それ以上無駄な走査を行わないようにする…という高度な最適化でもやってるんでしょうか.

3

update

2016/03/26 12:07

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -105,6 +105,6 @@
105
105
 
106
106
  - `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかるから.
107
107
  - `String#startsWith`は,V8においてはあまり最適化されておらず,`String#indexOf`よりも低速.一方SpiderMonkeyにおいては最適化されており,安定して高速.
108
- - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,「マッチしない長い文字列」において著しく動作が遅くなる傾向にある.
108
+ - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,**「マッチしない長い文字列」において著しく動作が遅くなる**傾向にある.
109
109
 
110
- V8の`String#indexOf`が「マッチしない長い文字列」に対して高速な理由が気になりますね.右辺の値を先に見て,それ以上無駄な走査を行わないようにする…という高度な最適化でもやってるんでしょうか.
110
+ V8の`String#indexOf`が**「マッチしない長い文字列」に対して高速**な理由が気になりますね.右辺の値を先に見て,それ以上無駄な走査を行わないようにする…という高度な最適化でもやってるんでしょうか.

2

考察

2016/03/26 11:58

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,59 +1,110 @@
1
+ # コード
2
+
1
3
  ```js
2
4
  'use strict';
3
5
 
4
6
  [
5
- '※abc',
7
+ ['※abc', 'マッチする短い文字列'],
6
- 'abc',
8
+ ['abc', 'マッチしない短い文字列'],
7
- '※' + new Array(10000).join('a'),
9
+ ['※' + new Array(10000).join('a'), 'マッチする長い文字列'],
8
- '' + new Array(10000).join('a'),
10
+ ['' + new Array(10000).join('a'), 'マッチしない長い文字列'],
9
- ].map(function (str, index) {
11
+ ].map(function (item) {
10
-
11
12
  var i;
13
+ var str = item[0];
12
14
 
13
- console.time('indexOf ' + index);
15
+ console.time('indexOf-' + item[1]);
14
16
  for (i = 0; i < 10000000; ++i) {
15
17
  str.indexOf('※') === 0;
16
18
  }
17
- console.timeEnd('indexOf ' + index);
19
+ console.timeEnd('indexOf-' + item[1]);
18
20
 
19
- console.time('RegExp ' + index);
21
+ console.time('RegExp-' + item[1]);
20
22
  for (i = 0; i < 10000000; ++i) {
21
23
  str.match(/^※/);
22
24
  }
23
- console.timeEnd('RegExp ' + index);
25
+ console.timeEnd('RegExp-' + item[1]);
24
26
 
25
- console.time('startsWith ' + index);
27
+ console.time('startsWith-' + item[1]);
26
28
  for (i = 0; i < 10000000; ++i) {
27
29
  str.startsWith('※');
28
30
  }
29
- console.timeEnd('startsWith ' + index);
31
+ console.timeEnd('startsWith-' + item[1]);
30
32
 
31
33
  console.log();
32
34
 
33
35
  });
34
36
  ```
35
37
 
38
+ # 結果
39
+
40
+ ## V8系
41
+
42
+ ###### Node.js
43
+
36
44
  ```
37
- indexOf 0: 422.819ms
45
+ indexOf-マッチする短い文字列: 451.954ms
38
- RegExp 0: 1139.455ms
46
+ RegExp-マッチする短い文字列: 1168.502ms
39
- startsWith 0: 656.991ms
47
+ startsWith-マッチする短い文字列: 656.937ms
40
48
 
41
- indexOf 1: 465.062ms
49
+ indexOf-マッチしない短い文字列: 451.098ms
42
- RegExp 1: 377.014ms
50
+ RegExp-マッチしない短い文字列: 377.314ms
43
- startsWith 1: 672.477ms
51
+ startsWith-マッチしない短い文字列: 673.922ms
44
52
 
45
- indexOf 2: 469.188ms
53
+ indexOf-マッチする長い文字列: 458.273ms
46
- RegExp 2: 1238.448ms
54
+ RegExp-マッチする長い文字列: 1188.736ms
47
- startsWith 2: 646.982ms
55
+ startsWith-マッチする長い文字列: 678.872ms
48
56
 
49
- indexOf 3: 458.261ms
57
+ indexOf-マッチしない長い文字列: 442.082ms
50
- RegExp 3: 388.297ms
58
+ RegExp-マッチしない長い文字列: 377.708ms
51
- startsWith 3: 664.676ms
59
+ startsWith-マッチしない長い文字列: 649.069ms
52
60
  ```
53
61
 
54
- `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかっているからでしょう.
62
+ ###### Chrome
55
63
 
56
64
  ```
65
+ indexOf-マッチする短い文字列: 676.688ms
66
+ RegExp-マッチする短い文字列: 1360.670ms
57
- > '※abc'.match(/※/)
67
+ startsWith-マッチする短い文字列: 1462.866ms
68
+
58
- [ '※', index: 0, input: '※abc' ]
69
+ indexOf-マッチしない短い文字列: 541.262ms
70
+ RegExp-マッチしない短い文字列: 617.367ms
71
+ startsWith-マッチしない短い文字列: 851.028ms
72
+
73
+ indexOf-マッチする長い文字列: 636.199ms
74
+ RegExp-マッチする長い文字列: 1344.160ms
75
+ startsWith-マッチする長い文字列: 1424.883ms
76
+
77
+ indexOf-マッチしない長い文字列: 506.433ms
78
+ RegExp-マッチしない長い文字列: 517.285ms
79
+ startsWith-マッチしない長い文字列: 780.458ms
59
- ```
80
+ ```
81
+
82
+ ## SpiderMonkey系
83
+
84
+ ###### Firefox
85
+
86
+ ```
87
+ indexOf-マッチする短い文字列: 284.28ms
88
+ RegExp-マッチする短い文字列: 3639.21ms
89
+ startsWith-マッチする短い文字列: 265.69ms
90
+
91
+ indexOf-マッチしない短い文字列: 276.58ms
92
+ RegExp-マッチしない短い文字列: 1038.85ms
93
+ startsWith-マッチしない短い文字列: 285.4ms
94
+
95
+ indexOf-マッチする長い文字列: 294.38ms
96
+ RegExp-マッチする長い文字列: 3774.39ms
97
+ startsWith-マッチする長い文字列: 303.2ms
98
+
99
+ indexOf-マッチしない長い文字列: 26592.07ms
100
+ RegExp-マッチしない長い文字列: 1386.18ms
101
+ startsWith-マッチしない長い文字列: 285.8ms
102
+ ```
103
+
104
+ # 考察
105
+
106
+ - `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかるから.
107
+ - `String#startsWith`は,V8においてはあまり最適化されておらず,`String#indexOf`よりも低速.一方SpiderMonkeyにおいては最適化されており,安定して高速.
108
+ - `String#indexOf`は,V8においてはあまり最適化されておらず,V8においては最適化されており,安定して高速.一方SpiderMonkeyにおいてはあまり最適化されておらず,「マッチしない長い文字列」において著しく動作が遅くなる傾向にある.
109
+
110
+ V8の`String#indexOf`が「マッチしない長い文字列」に対して高速な理由が気になりますね.右辺の値を先に見て,それ以上無駄な走査を行わないようにする…という高度な最適化でもやってるんでしょうか.

1

解説

2016/03/26 11:57

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -49,4 +49,11 @@
49
49
  indexOf 3: 458.261ms
50
50
  RegExp 3: 388.297ms
51
51
  startsWith 3: 664.676ms
52
+ ```
53
+
54
+ `String#match`が**マッチするときに遅い**となっているのは,返り値の生成にコストがかかっているからでしょう.
55
+
56
+ ```
57
+ > '※abc'.match(/※/)
58
+ [ '※', index: 0, input: '※abc' ]
52
59
  ```