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

回答編集履歴

2

追記

2019/09/30 00:14

投稿

退会済みユーザー
answer CHANGED
@@ -88,4 +88,104 @@
88
88
  ```
89
89
  やはり実測してみると面白いです。
90
90
  paiza.io を使用したので計測値は結構揺れました。(timeout するんで、回数も絞ってますw)
91
- 多分、php のバージョンによっても異なるはずなので、自身の環境で確認してみてください。
91
+ 多分、php のバージョンによっても異なるはずなので、自身の環境で確認してみてください。
92
+
93
+ **さらに追記**
94
+ ```php
95
+ <?php
96
+ function test_in_array($arr, $list){
97
+ $res = [];
98
+ foreach($arr as $value){
99
+ if(in_array($value[0], $list)){
100
+ $res[] = $value;
101
+ }
102
+ }
103
+ return $res;
104
+ }
105
+
106
+ function test_array_key_exists($arr, $list){
107
+ $list2 = array_fill_keys($list, TRUE);
108
+ $res = [];
109
+ foreach($arr as $value){
110
+ if(array_key_exists($value[0], $list2)){
111
+ $res[] = $value;
112
+ }
113
+ }
114
+ return $res;
115
+ }
116
+
117
+ function test_foreach($arr, $list){
118
+ $res = [];
119
+ foreach ($arr as $value){
120
+ foreach($list as $num){
121
+ if($value[0]===$num){
122
+ $res[] = $value;
123
+ }
124
+ }
125
+ }
126
+ return $res;
127
+ }
128
+
129
+ function test_sort($arr, $list){
130
+ $res = [];
131
+ foreach($arr as $value){
132
+ if(!isset($tmp[$value[0]])){
133
+ $tmp[$value[0]] = [];
134
+ }
135
+ $tmp[$value[0]][] = $value;
136
+ }
137
+ foreach($list as $num){
138
+ if(isset($tmp[$num])){
139
+ $res[] = $tmp[$num];
140
+ }
141
+ }
142
+ return $res;
143
+ }
144
+
145
+ foreach([[10000, 10], [1000, 10], [10000, 100], [100000, 100],] as [$arr_max, $list_max]){
146
+ $arr = [];
147
+ for($i = 0; $i < $arr_max; $i++){
148
+ $arr[] = [
149
+ rand(0, 100),
150
+ 'hoge',
151
+ 'fuga',
152
+ ];
153
+ }
154
+
155
+ $list = [];
156
+ for($i = 0; $i < $list_max; $i++){
157
+ $list[] = rand(0, 100);
158
+ }
159
+
160
+ echo 'test : arr_max = ' . $arr_max . ', list_max = ' . $list_max . PHP_EOL;
161
+ foreach(['test_in_array', 'test_foreach', 'test_sort', 'test_array_key_exists'] as $func){
162
+ $time_start = microtime(true);
163
+ $func($arr, $list);
164
+ $time = microtime(true) - $time_start;
165
+ printf("$func \t %.7f 秒\n",$time);
166
+ }
167
+ }
168
+ ```
169
+ ```
170
+ test : arr_max = 10000, list_max = 10
171
+ test_in_array 0.0010860 秒
172
+ test_foreach 0.0018811 秒
173
+ test_sort 0.0021858 秒
174
+ test_array_key_exists 0.0003760 秒
175
+ test : arr_max = 1000, list_max = 10
176
+ test_in_array 0.0000389 秒
177
+ test_foreach 0.0001709 秒
178
+ test_sort 0.0000539 秒
179
+ test_array_key_exists 0.0000341 秒
180
+ test : arr_max = 10000, list_max = 100
181
+ test_in_array 0.0010271 秒
182
+ test_foreach 0.0149219 秒
183
+ test_sort 0.0006859 秒
184
+ test_array_key_exists 0.0004339 秒
185
+ test : arr_max = 100000, list_max = 100
186
+ test_in_array 0.0258038 秒
187
+ test_foreach 0.1712370 秒
188
+ test_sort 0.0291610 秒
189
+ test_array_key_exists 0.0179920 秒
190
+ ```
191
+ 結論:array_key_exists() は早い!w

1

追記

2019/09/30 00:14

投稿

退会済みユーザー
answer CHANGED
@@ -1,3 +1,91 @@
1
1
  今の配列の持ち方だと効率化はできません。
2
2
 
3
- もし`$ar`が DB から取り出した値なのであれば、取り出すときの構造を工夫すれば効率の良い取り出しができるかと。
3
+ もし`$arr`が DB から取り出した値なのであれば、取り出すときの構造を工夫すれば効率の良い取り出しができるかと。
4
+
5
+ **追記**
6
+ 興味本位で、配列の持ち方の変更まで含めてパフォーマンスがどうなるか、コードを書いてみました。
7
+ ```php
8
+ <?php
9
+ function test_in_array($arr, $list){
10
+ $res = [];
11
+ foreach($arr as $value){
12
+ if(in_array($value[0], $list)){
13
+ $res[] = $value;
14
+ }
15
+ }
16
+ return $res;
17
+ }
18
+
19
+ function test_foreach($arr, $list){
20
+ $res = [];
21
+ foreach ($arr as $value){
22
+ foreach($list as $num){
23
+ if($value[0]===$num){
24
+ $res[] = $value;
25
+ }
26
+ }
27
+ }
28
+ return $res;
29
+ }
30
+
31
+ function test_sort($arr, $list){
32
+ $res = [];
33
+ foreach($arr as $value){
34
+ if(!isset($tmp[$value[0]])){
35
+ $tmp[$value[0]] = [];
36
+ }
37
+ $tmp[$value[0]][] = $value;
38
+ }
39
+ foreach($list as $num){
40
+ if(isset($tmp[$num])){
41
+ $res[] = $tmp[$num];
42
+ }
43
+ }
44
+ return $res;
45
+ }
46
+
47
+ foreach([[10000, 10], [1000, 10], [10000, 100], [100000, 100],] as [$arr_max, $list_max]){
48
+ $arr = [];
49
+ for($i = 0; $i < $arr_max; $i++){
50
+ $arr[] = [
51
+ rand(0, 100),
52
+ 'hoge',
53
+ 'fuga',
54
+ ];
55
+ }
56
+
57
+ $list = [];
58
+ for($i = 0; $i < $list_max; $i++){
59
+ $list[] = rand(0, 100);
60
+ }
61
+ echo 'test : arr_max = ' . $arr_max . ', list_max = ' . $list_max . PHP_EOL;
62
+ foreach(['test_in_array', 'test_foreach', 'test_sort'] as $func){
63
+ $time_start = microtime(true);
64
+ $func($arr, $list);
65
+ $time = microtime(true) - $time_start;
66
+ printf("$func \t %.7f 秒\n",$time);
67
+ }
68
+ }
69
+ ```
70
+ in_array が圧倒的に早いかと思ってましたが、そうでもないですね。
71
+ ```php
72
+ test : arr_max = 10000, list_max = 10
73
+ test_in_array 0.0011530 秒
74
+ test_foreach 0.0019360 秒
75
+ test_sort 0.0010860 秒
76
+ test : arr_max = 1000, list_max = 10
77
+ test_in_array 0.0000391 秒
78
+ test_foreach 0.0001721 秒
79
+ test_sort 0.0000541 秒
80
+ test : arr_max = 10000, list_max = 100
81
+ test_in_array 0.0010500 秒
82
+ test_foreach 0.0152941 秒
83
+ test_sort 0.0007241 秒
84
+ test : arr_max = 100000, list_max = 100
85
+ test_in_array 0.0273101 秒
86
+ test_foreach 0.1742241 秒
87
+ test_sort 0.0325580 秒
88
+ ```
89
+ やはり実測してみると面白いです。
90
+ paiza.io を使用したので計測値は結構揺れました。(timeout するんで、回数も絞ってますw)
91
+ 多分、php のバージョンによっても異なるはずなので、自身の環境で確認してみてください。