date関数か、DateTimeクラスか、DateTimeImmutableクラスか
元ネタは、直近でもないのですが、date関数で書いていたものがDateTimeクラスに書き換えられていた、ってのがありまして。
ふと「そういえば、色々とこの辺は今、どうなんだろう?」という疑問が出てきたのが初手のお話です。
で、先に。
「PHP5.5.0以降前提」にはなるのですが(しかも5.5の若いバージョンはたしか結構なバグがあったと伝聞)。
プログラムの上下で「日付を持ちまわる」のであれば、DateTimeImmutable一択なんじゃないかなぁ、とは思われます。
とりあえずなによりも「Immutable」ってのがよいぢゃぁないですか!! ないですか!! ないですか!!
んで。
「プログラムの上下で日付を取る」処理はともかくとして、「一か所だけで日付文字列がとりたい程度」の時はどうかなぁ? とか思ったのが大体の事の発端。
事前予想としては
・クラス系は、インスタンス作る分、ちょっとだけ重いんじゃなかろうか?
・メモリはまず食わないだろう
・とはいえ所詮軽微な処理なので、差はわずかなんじゃなかろうか
ってあたり。
以下のコードを流して、実験。
<?php $t = microtime(true); for($i = 0; $i < 100000; ++$i) { date(DATE_ATOM); } $t = microtime(true) - $t; var_dump( memory_get_usage(true) ); var_dump($t); echo "\n"; $t = microtime(true); for($i = 0; $i < 100000; ++$i) { (new DateTime())->format(DateTime::ATOM); } $t = microtime(true) - $t; var_dump( memory_get_usage(true) ); var_dump($t); echo "\n"; $t = microtime(true); for($i = 0; $i < 100000; ++$i) { (new DateTimeImmutable())->format(DateTime::ATOM); } $t = microtime(true) - $t; var_dump( memory_get_usage(true) ); var_dump($t);
結果は、こんなん。
int(2097152)
float(0.24294114112854)int(2097152)
float(0.57182097434998)int(2097152)
float(0.46780776977539)
int(2097152)
float(0.24283909797668)int(2097152)
float(0.37853217124939)int(2097152)
float(0.36751198768616)
int(2097152)
float(0.1880509853363)int(2097152)
float(0.38330698013306)int(2097152)
float(0.36089396476746)
微妙にふらつくのですが、おおむね「dateが一番早い」ってのは、予想通り。
メモリ的に「差異がない」ってのも、予想通り。
ほんのり予想はしてたのですが「DateTimeよりDateTimeImmutableのほうが早い」ってあたりは、いくつか仮説はつくものの、興味深いところかなぁ、と。
&
所詮「10万回ぶんまわしてこの数値」なので、結局のところ「誤差レベル」ともいえるかなぁ、とw
ここからすると…「持ちまわるなら(PHPのバージョンが真っ当なら)DateTimeImmutable」ってのは、ほぼコンセンサスが取れて。
「プログラム内で一か所しか日付系がない」場合
・date()関数かDateTimeクラスか、は、お好みorコーディング規約次第
・「考えるの面倒だから常にDateTimeImmutable」もあり
ってあたりからの選択かなぁ、と。斜めに見てる限り「DateTimeクラスで出来てdate関数群で出来ないこと」も、なさそうですしなぁ。
多分、当面のおいちゃん的には
・初心者相手に、或いはざっくりとコードを書くときはdate()関数を多用
・「ものすごく限界まで」速度を気にするコードはdate()関数:いやそもそも「PHP以外で書こうよ」って話はおいといてw
・きっちり書いてPHPバージョンが真っ当ならDateTimeImmutableクラス
って切り分けかなぁ……DateTimeクラスの出番がないw
「DateTimeクラス、この辺が便利〜」ってのがあったら、コメントなどで教えてくださいませw