phpコアから読み解く定石の嘘ホント #phpcon2013
DESCRIPTION
(PHPカンファレンス2013での講演内容です) 突然ですが…そのPHPの定石は正しいと言えるでしょうか?「echoの方がprintより速い」「エラー抑制演算子@は常に避けるべき」などなど、PHPを書く上で"定石"と呼ばれるコーディングスタイルがいくつもあります。それらの挙動をパフォーマンス計測とPHPの内部実装に踏み込みつつ、わかりやすく検証していきます。TRANSCRIPT
![Page 1: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/1.jpg)
PHPコアから読み解く
定石の嘘ホント
ヤフー株式会社 蒋(蒋池) 東龍
![Page 2: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/2.jpg)
2
レジュメ
• 前編(5分)
– もろもろ始める前に
• 中編(24分)
– エラー制御演算子
– 比較演算子
– 標準出力
• 後編(1分)
– おわり
![Page 3: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/3.jpg)
3
もろもろ始める前に
PHP における定石を
何か知っていますか?
![Page 4: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/4.jpg)
4
もろもろ始める前に
その定石は
どのようにして
正しいと判断しましたか?
![Page 5: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/5.jpg)
5
もろもろ始める前に
定石とは何でしょうか?
![Page 6: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/6.jpg)
6
もろもろ始める前に
デジタル大辞泉
より
![Page 7: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/7.jpg)
7
もろもろ始める前に
物事をするときの、
最上とされる方法・手順
![Page 8: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/8.jpg)
8
もろもろ始める前に
つまり
PHP の定石とは
![Page 9: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/9.jpg)
9
もろもろ始める前に
PHP でコーディングする時の
最上とされる方法・手順
![Page 10: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/10.jpg)
10
もろもろ始める前に
定石の良し悪しは
どうやって判断すれば
よいのでしょうか?
![Page 11: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/11.jpg)
11
もろもろ始める前に
数字 および 論理から
判断する必要がある
![Page 12: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/12.jpg)
12
もろもろ始める前に
数字に関しては……
![Page 13: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/13.jpg)
13
もろもろ始める前に
実行時の
速度を計測する
![Page 14: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/14.jpg)
14
もろもろ始める前に
コンパイルやネットワークを
計測しないようにするため
任意のコードを
microtime() で挟む
(単位は usec)
![Page 15: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/15.jpg)
15
もろもろ始める前に
<?php
$start = microtime(true);
$max = <計測回数>;
for($i = 0; $i < $max; $i++)
{
<該当処理>
}
$end = microtime(true);
$tm = $end - $start;
error_log("time[$tm]usec¥n");
//?>
![Page 16: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/16.jpg)
16
もろもろ始める前に
論理に関しては……
![Page 17: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/17.jpg)
17
もろもろ始める前に
スクリプトの
オペコードを解析する
![Page 18: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/18.jpg)
18
もろもろ始める前に
最小の命令単位である
オペコードについて考えるため
vld(Vulcan Logic Disassembler)
でダンプする
![Page 19: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/19.jpg)
19
もろもろ始める前に
<番号> <オペコード> <オペランド1> <オペランド2> ※オペコード=オペレーター=最小単位の処理 ※オペランド=引数 ※対応するハンドラは ZEND_*_HANDLER()
![Page 20: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/20.jpg)
20
もろもろ始める前に
答え(を覚えること)は
全く重要ではありません
![Page 21: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/21.jpg)
21
もろもろ始める前に
どっちの方が速いのか
どうしてそうなのか
考えてみることが重要!
![Page 22: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/22.jpg)
22
もろもろ始める前に
ここからは
クイズ形式です
![Page 23: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/23.jpg)
23
もろもろ始める前に
一人では寂しいので
双方向で進めさせてください!
![Page 24: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/24.jpg)
24
もろもろ始める前に
1問につき8分!
1. 出題(50秒)
2. 黙考(10秒)
3. 質問、挙手、指名(1分)
4. 回答(3分)
5. 考察(3分)
![Page 25: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/25.jpg)
25
エラー制御演算子
エラー制御演算子
なし vs あり
どっちが速い?
(100回計測)
![Page 26: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/26.jpg)
26
エラー制御演算子
for($i = 0; $i < $max; $i++) { include('nothing.php'); } ※nothing.phpは存在しない
for($i = 0; $i < $max; $i++) { @include('nothing.php'); } ※nothing.phpは存在しない
![Page 27: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/27.jpg)
27
エラー制御演算子
あれこれ
![Page 28: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/28.jpg)
28
エラー制御演算子
0.088059902191162 usec 0.085351943969727 usec
速い
![Page 29: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/29.jpg)
29
エラー制御演算子
11 INCLUDE_OR_EVAL 'nothing.php', INCLUDE
11 BEGIN_SILENCE 12 INCLUDE_OR_EVAL 'nothing.php', INCLUDE 13 END_SILENCE ~7
![Page 30: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/30.jpg)
30
エラー制御演算子
エラー制御演算子は一時的に
error_reporting を 0 にしている
エラーがあった時には
出力が減るので処理は速くなる
![Page 31: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/31.jpg)
31
比較演算子
比較演算子
($a == $b) vs ($a === $b)
どっちが速い?
(10万回計測)
![Page 32: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/32.jpg)
32
比較演算子
$a = "1"; for($i = 0; $i < $max; $i++) { if(1 == $a){ // } }
$a = "1"; for($i = 0; $i < $max; $i++) { if(1 === $a){ // } }
![Page 33: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/33.jpg)
33
比較演算子
あれこれ
![Page 34: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/34.jpg)
34
比較演算子
0.017616987228394 usec 0.0085439682006836 usec
速い
![Page 35: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/35.jpg)
35
比較演算子
!2 = $a 11 IS_EQUAL 1, !2
!2 = $a 11 IS_IDENTICAL 1, !2
![Page 36: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/36.jpg)
36
比較演算子
オペランドの型が違う時
== の場合には型変換を試みるが
=== の場合には型変換を試みない
型が違う場合には
=== の方がずっと速い
![Page 37: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/37.jpg)
37
標準出力
標準出力
print() vs echo()
どっちが速い?
(1000回計測)
![Page 38: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/38.jpg)
38
標準出力
for($i = 0; $i < $max; $i++) { print("abcdefghijklmn opqrstuvwxyz¥n"); }
※実際には1行
for($i = 0; $i < $max; $i++) { echo("abcdefghijklmn opqrstuvwxyz¥n"); }
※実際には1行
![Page 39: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/39.jpg)
39
標準出力
あれこれ
![Page 40: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/40.jpg)
40
標準出力
0.00041317939758301 usec 0.00037407875061035 usec
速い
![Page 41: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/41.jpg)
41
標準出力
10 PRINT 'abcdefghijklmn opqrstuvwxyz%0A’ (~6に結果)
※実際には1行 11 FREE ~6
10 ECHO 'abcdefghijklmn opqrstuvwxyz%0A’
※実際には1行
![Page 42: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/42.jpg)
42
標準出力
異なるオペコードだが
PRINT は ECHO を
ラッピングしていて戻り値もある
(必ず 1 が返る)
echo() を利用した方がよい
![Page 43: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/43.jpg)
43
おわり
定石は
前提条件によって
全く姿を変えてしまう
![Page 44: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/44.jpg)
44
おわり
だから
![Page 45: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/45.jpg)
45
おわり
定石は
使えることよりも
考えることの方が大切
![Page 46: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/46.jpg)
46
おわり
さらには
![Page 47: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/47.jpg)
47
おわり
ただ暗記するよりも
考えてみた方が
楽しいし覚えられる
![Page 48: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/48.jpg)
48
おわり
• オペコード
– http://blog.golemon.com/
• PHP コード最適化 Best Practices 63
– http://d.hatena.ne.jp/koto2/20080518/1211070116
![Page 49: PHPコアから読み解く定石の嘘ホント #phpcon2013](https://reader033.vdocuments.mx/reader033/viewer/2022050920/54b768324a795971038b45ab/html5/thumbnails/49.jpg)
49
おわり
ありがとうございました