49
PHPコアから読み解く 定石の嘘ホント ヤフー株式会社 蒋(蒋池) 東龍

PHPコアから読み解く定石の嘘ホント #phpcon2013

  • Upload
    yahoo

  • View
    7.576

  • Download
    3

Embed Size (px)

DESCRIPTION

(PHPカンファレンス2013での講演内容です) 突然ですが…そのPHPの定石は正しいと言えるでしょうか?「echoの方がprintより速い」「エラー抑制演算子@は常に避けるべき」などなど、PHPを書く上で"定石"と呼ばれるコーディングスタイルがいくつもあります。それらの挙動をパフォーマンス計測とPHPの内部実装に踏み込みつつ、わかりやすく検証していきます。

Citation preview

Page 1: PHPコアから読み解く定石の嘘ホント #phpcon2013

PHPコアから読み解く

定石の嘘ホント

ヤフー株式会社 蒋(蒋池) 東龍

Page 2: PHPコアから読み解く定石の嘘ホント #phpcon2013

2

レジュメ

• 前編(5分)

– もろもろ始める前に

• 中編(24分)

– エラー制御演算子

– 比較演算子

– 標準出力

• 後編(1分)

– おわり

Page 3: PHPコアから読み解く定石の嘘ホント #phpcon2013

3

もろもろ始める前に

PHP における定石を

何か知っていますか?

Page 4: PHPコアから読み解く定石の嘘ホント #phpcon2013

4

もろもろ始める前に

その定石は

どのようにして

正しいと判断しましたか?

Page 5: PHPコアから読み解く定石の嘘ホント #phpcon2013

5

もろもろ始める前に

定石とは何でしょうか?

Page 6: PHPコアから読み解く定石の嘘ホント #phpcon2013

6

もろもろ始める前に

デジタル大辞泉

より

Page 7: PHPコアから読み解く定石の嘘ホント #phpcon2013

7

もろもろ始める前に

物事をするときの、

最上とされる方法・手順

Page 8: PHPコアから読み解く定石の嘘ホント #phpcon2013

8

もろもろ始める前に

つまり

PHP の定石とは

Page 9: PHPコアから読み解く定石の嘘ホント #phpcon2013

9

もろもろ始める前に

PHP でコーディングする時の

最上とされる方法・手順

Page 10: PHPコアから読み解く定石の嘘ホント #phpcon2013

10

もろもろ始める前に

定石の良し悪しは

どうやって判断すれば

よいのでしょうか?

Page 11: PHPコアから読み解く定石の嘘ホント #phpcon2013

11

もろもろ始める前に

数字 および 論理から

判断する必要がある

Page 12: PHPコアから読み解く定石の嘘ホント #phpcon2013

12

もろもろ始める前に

数字に関しては……

Page 13: PHPコアから読み解く定石の嘘ホント #phpcon2013

13

もろもろ始める前に

実行時の

速度を計測する

Page 14: PHPコアから読み解く定石の嘘ホント #phpcon2013

14

もろもろ始める前に

コンパイルやネットワークを

計測しないようにするため

任意のコードを

microtime() で挟む

(単位は usec)

Page 15: PHPコアから読み解く定石の嘘ホント #phpcon2013

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

16

もろもろ始める前に

論理に関しては……

Page 17: PHPコアから読み解く定石の嘘ホント #phpcon2013

17

もろもろ始める前に

スクリプトの

オペコードを解析する

Page 18: PHPコアから読み解く定石の嘘ホント #phpcon2013

18

もろもろ始める前に

最小の命令単位である

オペコードについて考えるため

vld(Vulcan Logic Disassembler)

でダンプする

Page 19: PHPコアから読み解く定石の嘘ホント #phpcon2013

19

もろもろ始める前に

<番号> <オペコード> <オペランド1> <オペランド2> ※オペコード=オペレーター=最小単位の処理 ※オペランド=引数 ※対応するハンドラは ZEND_*_HANDLER()

Page 20: PHPコアから読み解く定石の嘘ホント #phpcon2013

20

もろもろ始める前に

答え(を覚えること)は

全く重要ではありません

Page 21: PHPコアから読み解く定石の嘘ホント #phpcon2013

21

もろもろ始める前に

どっちの方が速いのか

どうしてそうなのか

考えてみることが重要!

Page 22: PHPコアから読み解く定石の嘘ホント #phpcon2013

22

もろもろ始める前に

ここからは

クイズ形式です

Page 23: PHPコアから読み解く定石の嘘ホント #phpcon2013

23

もろもろ始める前に

一人では寂しいので

双方向で進めさせてください!

Page 24: PHPコアから読み解く定石の嘘ホント #phpcon2013

24

もろもろ始める前に

1問につき8分!

1. 出題(50秒)

2. 黙考(10秒)

3. 質問、挙手、指名(1分)

4. 回答(3分)

5. 考察(3分)

Page 25: PHPコアから読み解く定石の嘘ホント #phpcon2013

25

エラー制御演算子

エラー制御演算子

なし vs あり

どっちが速い?

(100回計測)

Page 26: PHPコアから読み解く定石の嘘ホント #phpcon2013

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

27

エラー制御演算子

あれこれ

Page 28: PHPコアから読み解く定石の嘘ホント #phpcon2013

28

エラー制御演算子

0.088059902191162 usec 0.085351943969727 usec

速い

Page 29: PHPコアから読み解く定石の嘘ホント #phpcon2013

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

30

エラー制御演算子

エラー制御演算子は一時的に

error_reporting を 0 にしている

エラーがあった時には

出力が減るので処理は速くなる

Page 31: PHPコアから読み解く定石の嘘ホント #phpcon2013

31

比較演算子

比較演算子

($a == $b) vs ($a === $b)

どっちが速い?

(10万回計測)

Page 32: PHPコアから読み解く定石の嘘ホント #phpcon2013

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

33

比較演算子

あれこれ

Page 34: PHPコアから読み解く定石の嘘ホント #phpcon2013

34

比較演算子

0.017616987228394 usec 0.0085439682006836 usec

速い

Page 35: PHPコアから読み解く定石の嘘ホント #phpcon2013

35

比較演算子

!2 = $a 11 IS_EQUAL 1, !2

!2 = $a 11 IS_IDENTICAL 1, !2

Page 36: PHPコアから読み解く定石の嘘ホント #phpcon2013

36

比較演算子

オペランドの型が違う時

== の場合には型変換を試みるが

=== の場合には型変換を試みない

型が違う場合には

=== の方がずっと速い

Page 37: PHPコアから読み解く定石の嘘ホント #phpcon2013

37

標準出力

標準出力

print() vs echo()

どっちが速い?

(1000回計測)

Page 38: PHPコアから読み解く定石の嘘ホント #phpcon2013

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

39

標準出力

あれこれ

Page 40: PHPコアから読み解く定石の嘘ホント #phpcon2013

40

標準出力

0.00041317939758301 usec 0.00037407875061035 usec

速い

Page 41: PHPコアから読み解く定石の嘘ホント #phpcon2013

41

標準出力

10 PRINT 'abcdefghijklmn opqrstuvwxyz%0A’ (~6に結果)

※実際には1行 11 FREE ~6

10 ECHO 'abcdefghijklmn opqrstuvwxyz%0A’

※実際には1行

Page 42: PHPコアから読み解く定石の嘘ホント #phpcon2013

42

標準出力

異なるオペコードだが

PRINT は ECHO を

ラッピングしていて戻り値もある

(必ず 1 が返る)

echo() を利用した方がよい

Page 43: PHPコアから読み解く定石の嘘ホント #phpcon2013

43

おわり

定石は

前提条件によって

全く姿を変えてしまう

Page 44: PHPコアから読み解く定石の嘘ホント #phpcon2013

44

おわり

だから

Page 45: PHPコアから読み解く定石の嘘ホント #phpcon2013

45

おわり

定石は

使えることよりも

考えることの方が大切

Page 46: PHPコアから読み解く定石の嘘ホント #phpcon2013

46

おわり

さらには

Page 47: PHPコアから読み解く定石の嘘ホント #phpcon2013

47

おわり

ただ暗記するよりも

考えてみた方が

楽しいし覚えられる

Page 48: PHPコアから読み解く定石の嘘ホント #phpcon2013

48

おわり

• オペコード

– http://blog.golemon.com/

• PHP コード最適化 Best Practices 63

– http://d.hatena.ne.jp/koto2/20080518/1211070116

Page 49: PHPコアから読み解く定石の嘘ホント #phpcon2013

49

おわり

ありがとうございました