phpのifとかインクリメントとかforとかwhileとかの速度を測ってみた

phpの高速化とか、いろいろ言われてるみたいなので計測してみた。


ちなみにphpのバージョンとか

php -v
PHP 5.5.3-1ubuntu2.2 (cli) (built: Feb 28 2014 20:03:35) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
    with Zend OPcache v7.0.3-dev, Copyright (c) 1999-2013, by Zend Technologies


==============================
インクリメント
==============================

++$i
$i++

とかってやつ

前に置くのか後ろに置くのか


計測はこんな感じ

// 100万回
$count = 1000000;
// ------------------------------
$i = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	++$i;
}
echo '++==           ',(microtime(true) - $time_start),"\n";
// ------------------------------
$i = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	$i++;
}
echo '==++           ',(microtime(true) - $time_start),"\n";

計測

++==           0.025747060775757
==++           0.029487133026123

++==           0.025246858596802
==++           0.028033971786499

++==           0.028851985931396
==++           0.028445959091187

++==           0.025568008422852
==++           0.027904033660889

++==           0.025285959243774
==++           0.028755903244019

++==           0.030179023742676
==++           0.035378932952881

++==           0.028646945953369
==++           0.028249979019165

++==           0.026021957397461
==++           0.028114080429077

++==           0.025579929351807
==++           0.02804708480835

++==           0.025492906570435
==++           0.028111934661865

全体的に前置きの方が早い



==============================
while / for
==============================

// 100万回
$count = 1000000;
// ------------------------------
$i = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	++$i;
}
echo 'while ',(microtime(true) - $time_start),"\n";
// ------------------------------
// 時間計測 start
$time_start = microtime(true);
for($i=0; $i < $count; ++$i) {
	// 処理
}
echo 'for   ',(microtime(true) - $time_start),"\n";

計測

while 0.025560855865479
for   0.029789924621582

while 0.028202056884766
for   0.029987096786499

while 0.025554895401001
for   0.029761075973511

while 0.024917840957642
for   0.030480861663818

while 0.025504112243652
for   0.029409170150757

while 0.025866031646729
for   0.031749963760376

while 0.025154113769531
for   0.030745983123779

while 0.029871940612793
for   0.030441999435425

while 0.026530981063843
for   0.03018593788147

while 0.026401042938232
for   0.030878067016602

ふむふむ while の方が早い

==============================
if
==============================

計測はこんな感じ

$str = 0;
$time = 0;
$j = 0;
while($j < 100) {
	$l = 0;
	// 時間計測 start
	$time_start = microtime(true);
	$i=0;
	while($i<10000) {
		// 処理
		if ( !$str ) { ++$l; } else {}
		++$i;
	}
	// 時間計測 end
	$time += (microtime(true) - $time_start);
	++$j;
}
echo '!$str        ',($time/100),"\n";

で、計測の種類は

$str = 1;

通常
	if ( $str == 1 ) { ++$l; } else {}
通常否定
	if ( $str != 0 ) { ++$l; } else {}
通常else
	if ( $str == 0 ) {} else { ++$l; }
通常否定else
	if ( $str != 2 ) {} else { ++$l; }
型固定
	if ( $str === 1 ) { ++$l; } else {}
型固定否定
	if ( $str !== 0 ) { ++$l; } else {}
型固定else
	if ( $str === 0 ) {} else { ++$l; }
型固定否定else
	if ( $str !== 2 ) {} else { ++$l; }
キャスト
	if ( (bool)$str ) { ++$l; } else {}
キャスト否定 $str = 0;
	if ( !(bool)$str ) { ++$l; } else {}
キャストelse $str = 0;
	if ( (bool)$str ) {} else { ++$l; }
キャスト否定else $str = 1;
	if ( !(bool)$str ) {} else { ++$l; }
自動変換 $str = 1;
	if ( $str ) { ++$l; } else {}
自動変換否定 $str = 0;
	if ( !$str ) { ++$l; } else {}
自動変換else $str = 1;
	if ( $str ) {} else { ++$l; }
自動変換否定else $str = 0;
	if ( !$str ) {} else { ++$l; }


計測してみた

==           0.00084389448165894
!=           0.00080935478210449
== else      0.00061706304550171
!= else      0.00052867412567139	←通常否定else
===          0.00083347082138062
!==          0.00084855318069458
=== else     0.00067429304122925
!== else     0.00057015180587769	←型固定否定else
(bool)       0.00089924812316895
!(bool)      0.00095925807952881
(bool) else  0.00064983129501343
!(bool) else 0.00069067716598511
$str         0.0006005072593689
!$str        0.00084683656692505
$str else    0.010544335842133
!$str else   0.0005558705329895		←自動変換否定else

==           0.00080350160598755
!=           0.00081058025360107
== else      0.00063539266586304
!= else      0.00052812814712524	←通常否定else
===          0.00084133386611938
!==          0.00085250377655029
=== else     0.00067556858062744
!== else     0.00057274580001831	←型固定否定else
(bool)       0.00086822748184204
!(bool)      0.00095577239990234
(bool) else  0.00064630508422852
!(bool) else 0.00068346261978149
$str         0.00059448719024658
!$str        0.00083303451538086
$str else    0.010544602870941
!$str else   0.00056445360183716	←自動変換否定else

==           0.00078647375106812
!=           0.0008014440536499
== else      0.00059204578399658
!= else      0.00050928831100464	←通常否定else
===          0.00081926107406616
!==          0.00086530447006226
=== else     0.00066134929656982
!== else     0.00057900905609131	←型固定否定else
(bool)       0.0008729362487793
!(bool)      0.00096801042556763
(bool) else  0.00066162109375
!(bool) else 0.00069899559020996
$str         0.00060688018798828
!$str        0.00083314180374146
$str else    0.010544993877411
!$str else   0.00055915355682373	←自動変換否定else

==           0.0008077335357666
!=           0.00080495834350586
== else      0.00061290502548218
!= else      0.00052176475524902	←通常否定else
===          0.00084131002426147
!==          0.00084612607955933
=== else     0.00068219661712646
!== else     0.00056463956832886	←型固定否定else
(bool)       0.00086448431015015
!(bool)      0.00095495462417603
(bool) else  0.00063484191894531
!(bool) else 0.00070585489273071
$str         0.00059179544448853
!$str        0.00084029912948608
$str else    0.010550107955933
!$str else   0.00056765079498291	←自動変換否定else

==           0.00080776214599609
!=           0.00081157922744751
== else      0.00060899972915649
!= else      0.00052092313766479	←通常否定else
===          0.00082566976547241
!==          0.00083958387374878
=== else     0.00066883087158203
!== else     0.00060428142547607	←型固定否定else
(bool)       0.00087606906890869
!(bool)      0.00095779657363892
(bool) else  0.00064838647842407
!(bool) else 0.00069203615188599
$str         0.00060815811157227
!$str        0.00084720373153687
$str else    0.010562527179718
!$str else   0.00057796716690063	←自動変換否定else

==           0.00079947710037231
!=           0.00080780029296875
== else      0.00061281204223633
!= else      0.00054699897766113	←通常否定else
===          0.00085015058517456
!==          0.00084063529968262
=== else     0.00066312313079834
!== else     0.00058452367782593	←型固定否定else
(bool)       0.00086906433105469
!(bool)      0.00095147371292114
(bool) else  0.0006475830078125
!(bool) else 0.00070225715637207
$str         0.00059796333312988
!$str        0.00084948062896729
$str else    0.010549254417419
!$str else   0.00056097507476807	←自動変換否定else

==           0.0008036732673645
!=           0.00080451250076294
== else      0.0006067967414856
!= else      0.00054666996002197	←通常否定else
===          0.00083556413650513
!==          0.00084874391555786
=== else     0.00068095445632935
!== else     0.000581955909729		←型固定否定else
(bool)       0.00088818788528442
!(bool)      0.00096608638763428
(bool) else  0.00064664363861084
!(bool) else 0.00070542335510254
$str         0.00061458587646484
!$str        0.00085886240005493
$str else    0.010540969371796
!$str else   0.00056567668914795	←自動変換否定else

==           0.00080641984939575
!=           0.00080418825149536
== else      0.00060648202896118
!= else      0.00051806688308716	←通常否定else
===          0.00083667278289795
!==          0.00085772037506104
=== else     0.00067311525344849
!== else     0.00062383890151978	←型固定否定else
(bool)       0.00098736763000488
!(bool)      0.00098950862884521
(bool) else  0.0006629467010498
!(bool) else 0.00069870710372925
$str         0.0006104040145874
!$str        0.00083919763565063
$str else    0.010552031993866
!$str else   0.00056995153427124	←自動変換否定else

==           0.00080819129943848
!=           0.0008289098739624
== else      0.000608811378479
!= else      0.00052607774734497	←通常否定else
===          0.00087904214859009
!==          0.00085135459899902
=== else     0.00067275047302246
!== else     0.00057468891143799	←型固定否定else
(bool)       0.00086857557296753
!(bool)      0.00097743988037109
(bool) else  0.00065792083740234
!(bool) else 0.00066883563995361
$str         0.00060683727264404
!$str        0.00085765600204468
$str else    0.010556607246399
!$str else   0.00056848526000977	←自動変換否定else

==           0.00081485986709595
!=           0.00080594778060913
== else      0.00059741497039795
!= else      0.00053483009338379	←通常否定else
===          0.0008381986618042
!==          0.00086311340332031
=== else     0.00067501068115234
!== else     0.00057529211044312	←型固定否定else
(bool)       0.0008860182762146
!(bool)      0.0010260081291199
(bool) else  0.00068770408630371
!(bool) else 0.00071557760238647
$str         0.000636305809021
!$str        0.00088781118392944
$str else    0.010583927631378
!$str else   0.00061318874359131	←自動変換否定else

全体的に[else]が早い

んで、型固定した方が遅い
キャストはしない方が早い
などなど。。。


通常否定else < 型固定否定else < 自動変換否定else
この状態になると

つまり
[!]で否定した後の[else]に通常処理を書く

で、いいのかな?



おっと、数値だけやって文字列やってない。。。

つーことで

テスト式

// 10万回
$count = 100000;
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str == '1' ) { ++$l; } else {}
	++$i;
}
echo '==           ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str != '0' ) { ++$l; } else {}
	++$i;
}
echo '!=           ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str == '0' ) {} else { ++$l; }
	++$i;
}
echo '== else      ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str != '1' ) {} else { ++$l; }
	++$i;
}
echo '!= else      ',(microtime(true) - $time_start),"\n";
// ------------------------------
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str === '1' ) { ++$l; } else {}
	++$i;
}
echo '===          ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str !== '0' ) { ++$l; } else {}
	++$i;
}
echo '!==          ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str === '0' ) {} else { ++$l; }
	++$i;
}
echo '=== else     ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str !== '1' ) {} else { ++$l; }
	++$i;
}
echo '!== else     ',(microtime(true) - $time_start),"\n";
// ------------------------------
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( (bool)$str ) { ++$l; } else {}
	++$i;
}
echo '(bool)       ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '0';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( !(bool)$str ) { ++$l; } else {}
	++$i;
}
echo '!(bool)      ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '0';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( (bool)$str ) {} else { ++$l; }
	++$i;
}
echo '(bool) else  ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( !(bool)$str ) {} else { ++$l; }
	++$i;
}
echo '!(bool) else ',(microtime(true) - $time_start),"\n";
// ------------------------------
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str ) { ++$l; } else {}
	++$i;
}
echo '$str         ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '0';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( !$str ) { ++$l; } else {}
	++$i;
}
echo '!$str        ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '0';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( $str ) {} else { ++$l; }
	++$i;
}
echo '$str else    ',(microtime(true) - $time_start),"\n";
// ------------------------------
$str = '1';
$i = 0;
$l = 0;
// 時間計測 start
$time_start = microtime(true);
while($i < $count) {
	// 処理
	if ( !$str ) {} else { ++$l; }
	++$i;
}
echo '!$str else   ',(microtime(true) - $time_start),"\n";

計測

==           0.015548944473267
!=           0.014337062835693
== else      0.012104988098145
!= else      0.012882947921753
===          0.0086619853973389
!==          0.0088100433349609
=== else     0.0073549747467041
!== else     0.0069398880004883
(bool)       0.0092308521270752
!(bool)      0.010520935058594
(bool) else  0.0074150562286377
!(bool) else 0.007789134979248
$str         0.0060341358184814
!$str        0.0083639621734619
$str else    0.0059399604797363
!$str else   0.0067751407623291

==           0.015239953994751
!=           0.014648914337158
== else      0.012043952941895
!= else      0.012790203094482
===          0.0087771415710449
!==          0.0089170932769775
=== else     0.0072450637817383
!== else     0.0071299076080322
(bool)       0.0091469287872314
!(bool)      0.010406970977783
(bool) else  0.0074951648712158
!(bool) else 0.0078911781311035
$str         0.005932092666626
!$str        0.0084738731384277
$str else    0.0055310726165771
!$str else   0.0069131851196289

==           0.015153884887695
!=           0.014053821563721
== else      0.012149095535278
!= else      0.01253604888916
===          0.0087130069732666
!==          0.0089118480682373
=== else     0.0064749717712402
!== else     0.0071840286254883
(bool)       0.0091409683227539
!(bool)      0.010242938995361
(bool) else  0.0068519115447998
!(bool) else 0.0082559585571289
$str         0.0064811706542969
!$str        0.0084939002990723
$str else    0.0054168701171875
!$str else   0.0065860748291016

==           0.014975070953369
!=           0.013978004455566
== else      0.012229919433594
!= else      0.012514114379883
===          0.0087230205535889
!==          0.011383056640625
=== else     0.0075981616973877
!== else     0.0072879791259766
(bool)       0.0093951225280762
!(bool)      0.010555982589722
(bool) else  0.0074648857116699
!(bool) else 0.0078539848327637
$str         0.0059690475463867
!$str        0.0089118480682373
$str else    0.0055639743804932
!$str else   0.00677490234375

==           0.015239000320435
!=           0.014360189437866
== else      0.012303829193115
!= else      0.01282811164856
===          0.0088140964508057
!==          0.0086750984191895
=== else     0.0071609020233154
!== else     0.007127046585083
(bool)       0.0092580318450928
!(bool)      0.010439872741699
(bool) else  0.007688045501709
!(bool) else 0.007857084274292
$str         0.005950927734375
!$str        0.0084309577941895
$str else    0.0053961277008057
!$str else   0.0068790912628174

==           0.018538951873779
!=           0.014241933822632
== else      0.01275110244751
!= else      0.012619972229004
===          0.0087759494781494
!==          0.0086419582366943
=== else     0.0074098110198975
!== else     0.0068299770355225
(bool)       0.0089588165283203
!(bool)      0.010534048080444
(bool) else  0.0072999000549316
!(bool) else 0.0078210830688477
$str         0.0061519145965576
!$str        0.0083420276641846
$str else    0.0058231353759766
!$str else   0.006403923034668

==           0.014724969863892
!=           0.014312982559204
== else      0.01166296005249
!= else      0.012858152389526
===          0.0089340209960938
!==          0.0085959434509277
=== else     0.0071568489074707
!== else     0.0068719387054443
(bool)       0.0092999935150146
!(bool)      0.010385990142822
(bool) else  0.0075409412384033
!(bool) else 0.0077919960021973
$str         0.0063819885253906
!$str        0.0083119869232178
$str else    0.0055348873138428
!$str else   0.0067510604858398

==           0.014368057250977
!=           0.014211893081665
== else      0.012056112289429
!= else      0.012476921081543
===          0.0088639259338379
!==          0.0094108581542969
=== else     0.0066511631011963
!== else     0.0072169303894043
(bool)       0.0089859962463379
!(bool)      0.011130809783936
(bool) else  0.0068080425262451
!(bool) else 0.0086359977722168
$str         0.0058929920196533
!$str        0.0082230567932129
$str else    0.0055389404296875
!$str else   0.0063560009002686

==           0.015030145645142
!=           0.014203071594238
== else      0.012665033340454
!= else      0.012655019760132
===          0.0096051692962646
!==          0.0088131427764893
=== else     0.0070569515228271
!== else     0.0070149898529053
(bool)       0.0090069770812988
!(bool)      0.010300159454346
(bool) else  0.0074088573455811
!(bool) else 0.0076589584350586
$str         0.0059001445770264
!$str        0.0082809925079346
$str else    0.0054481029510498
!$str else   0.0067589282989502

==           0.015043973922729
!=           0.014506101608276
== else      0.011787891387939
!= else      0.013069868087769
===          0.0092020034790039
!==          0.0094058513641357
=== else     0.0075061321258545
!== else     0.0072119235992432
(bool)       0.0094819068908691
!(bool)      0.010200977325439
(bool) else  0.0074639320373535
!(bool) else 0.0079600811004639
$str         0.0059030055999756
!$str        0.0082888603210449
$str else    0.0058419704437256
!$str else   0.0063679218292236

文字列の場合は、型固定した方が早いのね

でもって[else]は早いと。。。

単純な判定なら、自動変換で判断させたほうが早いみたい

ちなみにArrayの自動変換も文字列の自動変換と同じような速度でした。




==============================
まとめ?
==============================
数値判定は、型指定しない方がいい
文字列判定は、型指定した方がいい

自動変換早いぞー
キャストは、キャストオフ!
通常処理は[else]側へ

for より while 使え

インクリメントは前置き


こんな所かな?