2014年1月14日。本格的に日本が動き始める今週は大幅株安から

  • このエントリーをはてなブックマークに追加

成人式の連休からあけた14日の週は、日本が2014年度本格始動の週だ

いきなりの大幅株安。

日経平均は一時436円安、米国株安や円高を嫌気し売り優勢

米国市場と連動性の高い日本株式市場は、米国株安の影響で売り優勢。
また、国内にも買い材料が薄い正月明けなので、致し方ない面はある。

株安

東京都知事選

細川元首相が小泉純一郎元首相に都知事選での支援を要請する模様。
小泉氏はその要請を受ける情勢とのこと。
ここ最近、小泉氏は自民党寄りの動きより独断専行的な動きを強めており、息子の進次郎氏がつらい状況に陥っているとのこと。
自民は元自民党員で閣僚経験者の舛添要一氏を支援する方向でまとまりそうなので、細川氏と小泉氏のつながりは少し苦しいものがあるのかもしれない。

選挙

Shift-JISのcsvを大量に処理する

ある会社から提供されるデータはレコード数で1万件程度で、正直なところ、どうとでもなった。
その延長上で別の会社から提供されるデータを処理しようと思ったら、レコード数が実に40万レコード近くあり、ファイルサイズも700MB以上と巨大なファイルだった。
PHPで、設定されているメモリの上限に達する処理を行おうとすると、【Allowed memory size of ××…】というエラーでスクリプトが止まってしまう。
これはタイムアウトになってしまうのを回避しようとするというレベルとはわけが違う。
ハードウェア自体に1GBしかメモリを積んでいないとした場合、どんなに頑張ってもPHPでメモリ使用量1GB以上の処理をこなすのは困難ということになる。
スワップメモリという考えがLinuxサーバーの場合存在しているが、そのスワップメモリにしても基本的にはディストリビューションをインストールする時点で上限を決める。
なので、要はメモリとして使える量以上は捌き切れないということになる。
それでも処理をしたいと思った時パッと思いつく回避方法は二つあった。
一つは、処理を分散するということ。
CSVデータを処理しきれる量単位で分割して読み込み処理し、1クール終わったらメモリを解放して2クールに突入という感じで最後まで繰り返すというやり方。
小さなメモリでも、1クールを小さくすれば不可能ではない。
これは、PHPコードの書き方次第でできそうだと考えた。
もう一つは、そもそも大きなファイルの処理を行うために何か関数なりライブラリなりあるんじゃないか
ということである。雑な言い方をすれば分断してメモリをうまく使いまわす処理をコーディングして作るのではなく、何か関数なりライブラリなりを入れることで同じようなことを今のコードでやってくれたりしないのか。ということ。
また、今回なぜこんな面倒な話になっているのかというと、提供されているCSVデータがどこもかしこもShift-JISコードであることが原因である。
仮にUTF-8のデータであればこんなことをそもそも考えなくても処理できるらしい。UTF-8のコードのものはCSVレコード1行単位で処理を行うらしいので、1行のレコードサイズしかメモリを食わないらしい。Shift-JISはこのあたりが非常にうまく動かなくて、最後には文字化けを起こすそうだ。
その回避策として一時ファイルにCSVファイルを展開しUTF-8へコンバートする処理をしているのだが、この処理をうまく書き換えることでいい感じの処理ができるようになった。
そのときに参考にしたのが以下の2つの記事だ。

少しでも早く処理するために、データをメモリに持って処理したら早いんじゃないかと思って調べていたらここにたどり着いた

PHPでメモリ上に一時ファイルを作る

残念ながら、読み込みたいファイルが大きすぎて、処理は早くなりそうだがさすがにこれは使えない。
後に控えている次のCSVデータはさらに大きいので。。。
と、悩みつつ記事を読んでいくと、そのまま、まさにドンピシャの記事にたどり着いた。

巨大なSJISのCSVファイルをfgetcsv関数で処理する

最近まったくPHPの勉強をしていなくて、初心者レベルから脱していなかったが、今回少しステップアップした。
メモリの使い方は非常に勉強になった。
また、同時にMySQLも勉強した。

MySQLの一時テーブル

Temporary Table(一時テーブル)について

正直なことを言うと、存在は知っていながらも使うことはないとおもい全く使ってこなかった。
今回、同じテーブルを別のwhere句で何十回もselectを行う処理が必要で、MySQLがすでに重い状態になっていた。
また、今後joinでテーブル結合しその中で異なるwhere句で何十回もまわす処理も出そうだと感じていた。
テンポラリテーブルにjoinしてしまったデータをwhere句を入れずにまるまる格納しておけば、その後joinを使わずにテンポラリテーブルにあるデータを引っ張ればjoinの回数を減らせるだろうし、何より、”メモリ”に展開されるところが魅力だ。
このプログラムは公開するプログラムではなく、限られた人間のみが利用するので、同時接続数は多くても2~3なので、メモリ的な心配もあまりないので安心だ。
これはこれで使い勝手が良く、処理が速くなるので今後も使うことになるかなと思った。

SNSでもご購読できます。