肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

timezoneを指定するとstrftimeが速くなる

またもヒントをいただきましたので再挑戦.

わざわざ環境変数に入れなくても,PHP中でtimezoneを設定すればいいぽい.そして,UTCじゃなくても,TimeZoneを指定すると早くなるっぽい(!!)


スクリプト自体もid:ichii386さんのをヒントに(というかほとんどパクりでごめんなしあm(..)m)改良済み.
ちなみに,あのあと自分の前のスクリプト動かしてみたら,時間全然違ってた.0.1秒とか全然かかってなかった.(id:Yudoufuさんが私のを動かしたときと同じくらいで,0.065秒くらいだったかな) 前なにか間違った?>id:sotarok


で,今回はちょっと色々比較.

タイムゾーンUTC

ソース

<?php

date_default_timezone_set('UTC');
$year = intval($argv[1]);
for ($i = mktime(0, 0, 0, 1, 1, $year), $date_e = mktime(0, 0, 0, 12, 31, $year);$i <= $date_e ; $i += 86400) {
    echo strftime("%m/%d", $i) . "\n";
}

ベンチマーク

% time php date_dump.php 2007 >/dev/null

real    0m0.031s
user    0m0.003s
sys     0m0.028s

平均0.030秒くらい

タイムゾーンAsia/Tokyo

ソース

<?php

date_default_timezone_set('Asia/Tokyo');
$year = intval($argv[1]);
for ($i = mktime(0, 0, 0, 1, 1, $year), $date_e = mktime(0, 0, 0, 12, 31, $year);$i <= $date_e ; $i += 86400) {
    echo strftime("%m/%d", $i) . "\n";
}

ベンチマーク

% time php date_dump_tokyo.php 2007 >/dev/null

real    0m0.028s
user    0m0.000s
sys     0m0.028s

たまたま↑はUTCより速いけど,平均的にはまったく同じ.

タイムゾーン指定ナシ

ソース

<?php

$year = intval($argv[1]);
for ($i = mktime(0, 0, 0, 1, 1, $year), $date_e = mktime(0, 0, 0, 12, 31, $year);$i <= $date_e ; $i += 86400) {
    echo strftime("%m/%d", $i) . "\n";
}

ベンチマーク

% time php date_dump_notimezone.php 2007 >/dev/null

real    0m0.044s
user    0m0.005s
sys     0m0.040s

平均0.045秒くらい

おっそ!

ちなみに,Datetimeオブジェクト

id:Yudoufuさんのコードでベンチマーク

% time php date_dump_yu.php 2007 >/dev/null

real    0m0.035s
user    0m0.004s
sys     0m0.031s

平均的には,0.036秒くらいかな.

ltraceでなにが起こってるか調べる

どうやら,タイムゾーンを指定しないと,

strcasecmp("JST", "ほにゃらら")                         = ほにゃ

とかいうものがとんでもなくひたすら呼ばれてるっぽい.

ログの量の違いでその怖さを実感.

% ls -l
合計 33772
(ry
-rw-rw-r--  1 sotaro sotaro  4446900  1月 28 05:11 log.txt     ←タイムゾーンUTC
-rw-rw-r--  1 sotaro sotaro 25394631  1月 28 06:28 log2.txt    ←タイムゾーン指定ナシ
-rw-rw-r--  1 sotaro sotaro  4448643  1月 28 06:18 log3.txt    ←タイムゾーンTokyo

デフォルトのタイムゾーンphp.iniで指定する

php.iniで.これを指定すると,スクリプト中でタイムゾーンを設定しなくても,ほぼ同じ速度がでました.

[Module Setting]のところです.

[Date]
; Defines the default timezone used by the date functions
date.timezone = Asia/Tokyo

検討のため,C言語で実装する

....が,実はここが一番時間かかった.めっちゃかかった.C言語で日付扱ったの初めてだった.超悔しいけどなんかへたくそです.添削してくれると嬉しいです><

ソースコード

#include<stdio.h>
#include<time.h>

int main(int argc, char *argv[])
{
    char date[6];
    time_t date_tmp;
    struct tm *date_t;
    int year = atoi(argv[1]);
    
    time(&date_tmp);
    date_t = localtime(&date_tmp);
    
    date_t->tm_year = year - 1900;
    date_t->tm_mon = 0;
    date_t->tm_mday = 1;

    while (year == date_t->tm_year + 1900) {
        strftime(date, 6, "%m/%d", date_t);
        printf("%s\n",  date);
        date_t->tm_mday += 1;
        date_tmp = mktime(date_t);
        date_t = localtime(&date_tmp);
    }
}

まぁとりあえずベンチマーク

% time ./a.out 2007 > /dev/null

real    0m0.004s
user    0m0.003s
sys     0m0.001s

まとめ

C言語は難しい.そして速い.
そろそろC言語の勉強しなおすことをホンキで考え出した.Pythonよりそっちじゃね?