がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

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