Python の datetime.strptime がすんごく遅い件
会社でRADIUSサーバーの認証ログをリアルタイムに解析するツールを作っていたところ、思ったようなパフォーマンスが出ず、line_profiler というプロファイリングツールを使って調べたところ、処理時間の大部分を datetime.strptime で日時の文字列を datetime オブジェクトに変換する一行のコードが占めていました。
strptime だけでスクリプト実行時間の83%を占めている。あきらかにここが原因
そこで、日時の文字列を自分で区切って datetime.datetime() に渡すようにしたところ、処理速度が飛躍的に向上しボトルネックは無くなりました。
下記サンプルコードを使ってベンチマークをしたところ、strptime はなんと4倍以上遅い!(実行環境: macOS Sierra / Python 3.5.2)
from datetime import datetime import time logtime_str = '20170101123456' start = time.time() for i in range(100000): dt = datetime.strptime(logtime_str, '%Y%m%d%H%M%S') print('strptime: {:.4f}sec, dt:{}'.format(time.time() - start, dt)) # strptime: 2.2368sec, dt:2017-01-01 12:34:56
from datetime import datetime import time logtime_str = '20170101123456' start = time.time() for i in range(100000): dt = datetime( year=int(logtime_str[0:4]), month=int(logtime_str[4:6]), day=int(logtime_str[6:8]), hour=int(logtime_str[8:10]), minute=int(logtime_str[10:12]), second=int(logtime_str[12:14]) ) print('self parse: {:.4f}sec, dt:{}'.format(time.time() - start, dt)) # self parse: 0.5266sec, dt:2017-01-01 12:34:56
Python 標準のプロファイリングライブラリ cProfile を視覚化する Python Call Graph というツールを使ってみました。
正規表現は使い回しされているようですが、なぜか毎回ロケール情報を取りに行っていて結構な時間がかかっているようです。今回のコードでは使っていませんが、strptime は曜日( 'Monday', '月曜' )なども取り扱えるため、ロケールを解釈する処理が入っているのでしょうか。それにしても時間かかりすぎてません?使い方間違ってるのかな・・・。
テキストのパースは奥が深いことはわかりますが、よく使う標準ライブラリにこのような罠があるというのは少しショックです。。。
ほかの言語でも遅い?
(2016/11/8追記) 他の言語はどうなんだろうと思い、力不足ながらも比較してみました
vs Ruby
まずは、意識高い系言語 Ruby。こんなただ ruby の構文に置き換えただけのコード、Rubyist に見られたら八つ裂きにされそうですが、どうか勘弁してください。
miyahan$ ruby -v ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
require 'date' require 'time' logtime_str = '20170101123456' start = Time.now for i in 0..100000 do dt = DateTime.strptime(logtime_str, '%Y%m%d%H%M%S') end print('DateTime.parse: ', Time.now - start, 'sec. ') print('dt: ', dt, "\n") # DateTime.parse: 0.30088sec. dt: 2017-01-01T12:34:56+00:00
require 'date' require 'time' logtime_str = '20170101123456' start = Time.now for i in 0..100000 do dt = DateTime.new( logtime_str[0, 4].to_i, logtime_str[4, 2].to_i, logtime_str[6, 2].to_i, logtime_str[8, 2].to_i, logtime_str[10, 2].to_i, logtime_str[12, 2].to_i ) end print('DateTime.new: ', Time.now - start, 'sec. ') print('dt: ', dt, "\n") # DateTime.new: 0.198785sec. dt: 2017-01-01T12:34:56+00:00
手動パースしたほうが34%ほど高速
vs PHP
次に、私の愛するゆるふわ言語 PHP。久しぶりに書くとドルやらセミコロンやらカッコやら面倒くさい。
miyahan$ php --version PHP 7.0.12 (cli) (built: Oct 14 2016 09:56:59) ( NTS ) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
<?php $logtime_str = '20170101123456'; $start = microtime(true); for ($i=0; $i<100000; $i++) { $dt = \DateTime::createFromFormat('YmdHis', $logtime_str); } print('DateTime:'.number_format(microtime(true) - $start, 5)."sec, "); print("dt:".$dt->format('Y-m-d H:i:s')."\n"); # DateTime:0.21719sec, dt:2017-01-01 12:34:56
<?php $logtime_str = '20170101123456'; $start = microtime(true); for ($i=0; $i<100000; $i++) { $ts = mktime( substr($logtime_str, 8, 2), substr($logtime_str, 10, 2), substr($logtime_str, 12, 2), substr($logtime_str, 4, 2), substr($logtime_str, 6, 2), substr($logtime_str, 0, 4) ); } print('mktime:'.number_format(microtime(true) - $start, 5)."sec, "); print("dt:".date('Y-m-d H:i:s', $ts)."\n"); # mktime:0.18713sec, dt:2017-01-01 12:34:56
<?php $logtime_str = '20170101123456'; $start = microtime(true); for ($i=0; $i<100000; $i++) { $ts = gmmktime( substr($logtime_str, 8, 2), substr($logtime_str, 10, 2), substr($logtime_str, 12, 2), substr($logtime_str, 4, 2), substr($logtime_str, 6, 2), substr($logtime_str, 0, 4) ); } print('gmmktime:'.number_format(microtime(true) - $start, 5)."sec, "); print("dt:".date('Y-m-d H:i:s', $ts)."\n"); # gmmktime:0.14538sec, dt:2017-01-01 12:34:56
手動パースは、モダンな DateTime クラス を使うより33%高速。ただし、GMTと見なして処理する gmmktime() の代わりに、自環境のタイムゾーンを考慮する mktime() を使うと、その差は14%ほどに縮まるので、DateTime クラスを使うことのオーバーヘッドはそこまでないと思います。
まとめ
言語 | 高級な方法 | 高速な方法 | 比 |
---|---|---|---|
Python 3.5 | 2.2368s | 0.5266s | 428% |
Ruby 2.3 | 0.3009s | 0.1988s | 151% |
PHP 7.0 | 0.2172s | 0.1454s | 149% |
Ruby も PHP も高級な機能を使うことによりで処理時間が50%ほど増えています。ただ一般的なアプリケーションであれば、その柔軟で強力な機能を簡潔なコードで実現できるというメリットに対して、十分ペイできるオーバーヘッドだと思います。一方 Python は428%とちょっと許容できない、というかバグじゃないかと疑うレベルです・・・。
Mac mini のメモリをRMAするの巻
これまでの流れ
('A`) ...
無限アップデート地獄
先日、自宅サーバーとして使っている Mac mini (Mid 2011) を macOS Sierra にアップグレードしようとしたところ、インストール → 失敗 → 再起動 → インストール → 失敗... の無限ループに陥り起動しなくなってしまいました。
指示通り AHT (Apple Hardware Test) をしてみると、テストの途中でフリーズしてしまいました。何らかのハードウェア障害が発生しているようです。ためしにメモリを昔使っていたものに取り替えてみたところ、AHTが完走し、Sierraのアップデートも無事完了しました。
たしかに以前からたまにカーネルパニックが起きたり、kaspersky でたびたび「ウイルス定義ファイルが破損しています」という警告がでたりと不安定ではありました。なるほどメモリか。メモリに乗ってるウイルス定義ファイルのデータが化けて、チェックサムか何かで検出された的な?
Let's RMA
現在使用しているメモリはCFD販売の永久保証がついたものだったので、お言葉に甘えて交換してもらうことに。
CFD販売は基本的に販売店対応になるらしいのですが、自分の場合は Amazon (通販) で買ったので、CFD販売 サポート案内 にあるテンプレを記入して直接メーカーにメール。2日後に返信があり、次のものをそろえて返品受付センタに送ってくれとのこと。
荷物を送った数日後、よくある「終売品につき、同等品への変更でもいい?」みたいな連絡がきつつ、計一週間で代替品が届きました。日本語だと楽ですねー。
さっそく Mac mini に取り付け。
それにしても、立て続けに Mac が3台故障・・・。Mac Pro の修理に5万、iMac の買い替えに25万。そして iPad Pro で 9万、iPhone 7 plus で 10.5万・・・。今年はどんだけアップルに貢いでるんだw
iMac サルベージ中に Mac Pro が故障するの巻
iMac 壊れる
先日、妹が使っている 24インチ iMac Early 2009 でカーネルパニックが頻発するようになり、まともに使えなくなりました。fsck すると修正不可能などファイルシステムの破損が進んでおり、これが原因だと思いました。
データは Time Machine で外付けHDDにバックアップしているものの、内蔵HDDをフォーマットしてOS・データを復旧している間に Time Machine が壊れると、妹の全人生のデータが失われてしまうため、綱渡り状態は避けたいところです。*1
そこで安全のために内蔵HDDのクローンを作成してから再インストールしようと、iMac をターゲットディスクモードにしつつ、私の Mac Pro Mid 2010 に FireWire で接続し Data Rescue というソフトでデータの復旧を行いました。
Mac Pro も壊れる
データの吸い出しには数十時間かかるらしいので、Mac Pro を動かしたまま会社に行ったのですが、帰宅すると電源が落ちていました。
え、なんで・・・?と思いながら電源スイッチを押すと・・・ 起動しない・・・
よくみると電源ランプが点滅しています。ググってみると、どうやら POST NG を示しているようです。「まあどうせメモリ故障だろう」と気軽な気持ちで切り分け開始。
- SMCリセット(電源ケーブルを抜いてしばらく放置):NG
- RAM抜き差し:NG
- RAM組み替え:NG
- CPUカード抜き差し:NG
- ビデオカード抜き差し:NG
- ストレージ(HDD,SSD,DVDドライブ)取り外し:NG
- ビデオカード取り外し:NG
- RAM取り外し:NG
全滅・・・
DRAMを1枚も刺していない状況で事象が変化しない*2ということは、わりと始めのほうで実行されるであろうメモリテストにすら到達していないということで、つまりはロジックボード(マザーボード)または電源が故障している可能性が濃厚です。
Mac Pro 修理を決意
完全に壊れてしまった Mac Pro。問題は修理するか買い替えるかという話。買ってから既に5年半が経過しているので十分買い替えてもよい時期ではあるのですが、現行の Mac Pro は6コアモデルですら50万円オーバー。しかもCPUは2世代も前の Xeon E5 v2 で正直言って魅力ゼロです。さらにこの Mac Pro は初ボーナスで盛りに盛った 12コア24スレッドモデル。GPUの時代遅れ感は否めませんが、CPUパワーは現行の 6core モデルと同等で、まだまだ十分に戦えます。
二週間悩んだ末、修理してがんばってもらうことにしました。次の問題はどこに修理に出すかという点ですが、Mac の修理方法はざっくり分けて3種類あります。
- Apple 純正サービス "AppleCare" を利用する(宅配業者を使ったセンドバック or Apple Store 持ち込み)
- pros : 安心
- cons : ネジ1本でも5万円の一律料金
- Apple正規サービスプロバイダに依頼する(ビックカメラ等)
- ためしにビックカメラのサイトを見てみると「準備中」のページだらけで料金体系が不明瞭(わざとか?)
- 非正規の修理サービスを利用する
- pros : 安くすむ(かもしれない)
- cons : 基本的に中古品での共食い整備、修理できない場合も多い
今回はロジックボード交換になる可能性が高いと判断し、AppleCare を利用することにしました。
Mac Pro ドナドナされる
さすがに Mac Pro を担いで電車で銀座に行くのは何なので、センドバック修理にします。
まず、Apple の 保証状況の確認 ページでシリアルナンバーを入力します。結果が表示されたら "修理のお申し込み" に進み、トラブルの内容を選択します。今回は ハードウェアの問題 → 電源が入らない を選びました。
つぎにサポートの方法を選択します。今回は電話を選びました。
なんと電話1回につき3000円を請求されます!!ここでだいぶ右往左往したのですが、結論を言うと 有償修理の依頼であればサポート料金は不要でした。そのまま進めると指定した番号に電話がかかってきて、5分くらいでサポートセンタにつながりました。あとは淡々と事象を説明し、回収日や支払い方法決めて修理依頼が完了。ちなみに今回はカード払いにしたのですが、電話終了後、すぐに請求メールが飛んできてアップルのサイトで決済を行いました。
デスクの足がジャマで取り出せず、仕方ないのでベランダからお迎えにあがるの図
Mac Pro 帰ってくる
8/31 にピックアップしてもらい、9/2 に修理完了、そして 9/3 に到着。3日間のスピード修理でした。
気になる修理内容ですが、やはりロジックボード不良だったようで丸ごと交換されていました。さらにビデオカードにも故障が内在していたらしく交換されていました。また電話でさりげなく伝えていたドライブベイの振動吸収用のゴムワッシャーが劣化していた件も、ベイの丸ごと交換で対応してもらえていました。
結果的に5万円ペイするだけの価値はあったと思います。まあ正直、RADEON HD 5770 の新品が手には入ってもうれしくも無いですがw
iMac おまえか?
Mac Pro が復活したので、妹 iMac のデータ吸い出しを再開しようと FireWire ケーブルを刺した瞬間、Mac Pro の電源が落ち、うんともすんとも言わなくなりました。慌てて FireWire ケーブルを抜くと、正常に起動するようになりました。
iMac、貴様が壊したのか・・・?
FireWire 経由で変な電気が流れて、Mac Pro のロジックボードが昇天。もともと FireWire は大容量のバスパワーを持っているために壊れやすいと言われているだけに、十分あり得る話です・・・。
というわけでデータ吸い出しは中止。代わりに Time Machine 用HDDのクローンを作成し、iMac のOS再インストールを行いました。これで治ると思いきや、インストール中にカーネルパニックが発生。何度ためしてもダメ。つまりファイルシステムの破損ではなく、ハードウェア故障が原因だったのです。結局、iMac のほうは買い替えることにしました。
なんだか iMac に壊された感が強いオレの Mac Pro。まあなんだ、これからもよろしく。
余談
Mac Benchmarks - Geekbench Browser をみると、Mac Pro Mid 2010 (Dual 6core 2.66GHz) って、iMac 特松とどっこいなのね・・・。今使ってるモニタ(NEC LCD2690WUXi)もヘタってきて買い替えたいし、ふつうに iMac に行った方がよかったかしらw
ルーターのコンフィグを git にぶち込んで世代管理してみたはなし
この記事を三行で
- みんな好き勝手な名前でコンフィグファイルをアップロードしてサーバーがパンク&どれが最新版かわからない状況に
- 命名規則を作り、サーバーに置いておくコンフィグを最新世代1つのみとした
- さらにファイルを社内 GitLab に自動アップロードし履歴確認ができるようにした
※ GitLab を入れ物として使うだけで、git を使ったワークフローを導入したとかのカッコイイ話じゃありません
あらまし
とある通信会社の委託でIPネットワークの監視作業員をやっています(非エンジニア)。うちの会社ではルーター・スイッチ類のコンフィグをTFTPサーバーへアップロードしてバックアップとしていますが、先日そのサーバーで反応が5分くらい返ってこなかったり、ファイルのアップロードに失敗したりと動作が不安定に・・・。HDDでも壊れたかな?と思いながら調べてみると...
$ df -h Filesystem サイズ 使用 残り 使用% マウント位置 /dev/cciss/c0d0p3 195G 195G 0 100% / /dev/cciss/c0d0p1 99M 13M 81M 14% /boot
Σ(;゙゚ω゚) ディスクフル!!!!
$ ll /var/tftp/ | wc -l 239662
Σ(;゙゚ω゚) 24万ファイル!!!!
この異常なまでの膨大なファイルは、いろんな組織や人間が好き勝手な名前でコンフィグをアップロードしてきたなれの果てです。ホスト1つを取っても、こんな感じでファイルがうじゃうじゃ出てきます。
$ ll /var/tftp | grep tkycore01 -rw-rw-rw- 1 nobody nobody 124862 10月 10 2015 20140303_tkycore01-confg -rw-rw-rw- 1 nobody nobody 127522 10月 10 2015 after_tkycore01.config -rw-rw-rw- 1 nobody nobody 123456 10月 10 2015 before_tkycore01.config -rw-rw-rw- 1 nobody nobody 122899 10月 10 2015 tkycore01 -rw-rw-rw- 1 nobody nobody 123456 10月 10 2015 tkycore01-confg -rw-rw-rw- 1 nobody nobody 126984 10月 10 2015 tkycore01-confg.txt -rw-rw-rw- 1 nobody nobody 119853 10月 10 2015 tkycore01-confg-old -rw-rw-rw- 1 nobody nobody 127556 10月 10 2015 tkycore01-confg_20130712.config -rw-rw-rw- 1 nobody nobody 126574 10月 10 2015 tkycore01-config
しかも以前に行ったサーバーの引っ越し時にタイムスタンプが狂ってしまった(属性のコピーを忘れた)らしく、もはやどれが最新のファイルかわからない状態に・・・。しかもこれが原因で誤って古いコンフィグで設備を復旧させてしまい、通信障害を起こしてしまった事故が何度も起きています。(ちなみに社内では、ヒューマンエラーに起因する障害を "人為故障" と呼ぶ)
対策方針
ふつうなら RANCID あたりで管理すべきところですが、うちの会社は優れたオープンソースソフトウェアを導入したり、ワークフローを大きく変えることに強い抵抗があるため、あくまで従来の暖かみのあるマニュアルオペレーション()を踏襲しつつ、差分管理のみを自動化することにしました。というわけで立てた方針がコチラ。
- TFTPサーバーに保存しておくコンフィグは最新世代一つのみとし、ファイル名は Cisco ライクに
ホスト名-confg
に統一する - 定期的にTFTPサーバー上の変更されたファイルを 社内GitLab へ自動アップロードし、バックアップ兼ヒストリーとして活用する
これによって、作業者のオペレーションは次のようになります。
Before
- ダウンロード : TFTPサーバーをホスト名で検索し、中身を見比べて最新ファイルを探して取得する = オペミスの恐れ!!
- アップロード : 特にルールがなく、上書きしたり、ファイル名に日付をつけたり様々 = オートメーション化できない
After
- ダウンロード:
ホスト名-confg
で取ってくる - アップロード:
ホスト名-confg
で上げる
と、シンプルなオペレーションになりました。
続きを読む9.7インチ iPad Pro ディスプレイレビュー
こんにちは、miyahan.com のミヤハンです。このたび私のブログ "miyalog" をはてなブログへ引っ越しいたしました。今後ともよろしくお願いします。(いろいろ理由はあるけど、markdown でブログ書きたかったってのが一番大きい)
iPad Pro がやってきた
実はいままで使っていたタブレットがなんと iPad 2 でして、IOSバージョンアップのたびに動作がもっさりになっていき、とうとう日本語入力すらままならない状況に陥っていました。iPad Air 3 のおあずけを食らい日々枕を涙で濡らす毎日でしたが、待ちに待った iPad Pro 9.7" の発表に即日ばいなう。待ち焦がれた1年間に比べれば、RAMが少し少なかったりカメラがもっこりしていることなど些細な問題です。
すでに iPad のレビューなど何百、何千とあるでしょうから、本記事では iPad Pro で刷新されたディスプレイに焦点を当て、データを交えて語りたいと思います。
iPad Pro 9.7” ディスプレイ性能検証
"Pro Display" と称したディスプレイは、iPad Air 2 と比べ輝度(ブライトネス)が25%、色域(カラーガマット)が25%向上しており、グレア(外光の映り込み)を40%低減しているとのことです。
まずグレアについては、画面に映り込む照明のシルエットが明らかに薄くなっており低反射コーティングが進化していることが見て取れます。ただ私の場合は液晶保護シートを貼ってしまったので、この恩恵は受けられません。ごめんねフィル。
次に輝度・色域について、x-rite の分光測色計 "ColorMunki" を使って、そのポテンシャルを測定しました。条件は次の通りです
- iPad 2
- 明るさ : 最大
- 明るさの自動調整 : OFF
- iPad Pro 9.7"
- 明るさ : 最大
- 明るさの自動調整 : OFF
- True Tone : OFF
- Night Shift : OFF
輝度・コントラスト比・色温度
iPad 2 | iPad Pro 9.7" | |
---|---|---|
最大輝度 | 380cd/m2 | 470cd/m2 |
黒レベル | 0.48cd/m2 | 0.51cd/m2 |
コントラスト比 | 800:1 | 920:1 |
色温度 | 6700K | 6650K |
色温度 Δuv | 0.0038 | 0.0003 |
iPad Pro 9.7" は 明るさが iPad 2 と比べ24%ほどアップしています。なお、ITmedia “新しいiPad”を正しい色の液晶ディスプレイと見比べる を見るに、私の iPad 2 はかなり明るい個体のようです。iPad 2 が 350cd/m2、iPad 3 〜 Air 2 が 420cd/m2 となると順当な進化と言えるでしょう。
コントラスト比は 800:1 から 920:1 と少し向上していますが測定誤差な気もします。また色温度はどちらも 6700K 前後と、標準規格の 6500K よりわずかに高め(青め)となっています。
色域
iPad 2 and iPad Pro 9.7" Color Gamut (グレイ部分が sRGB)
次に色域ですが、見ての通り大幅に向上しています。ITmedia “新しいiPad”を正しい色の液晶ディスプレイと見比べる を見ると、iPad 2 → iPad 3 のときに色域が大幅に広がり、今回さらにグリーンの色純度が高くなりほぼ sRGB をカバーするようになったようです。それにしても疑似白色LEDは赤の発色が苦手なのですが、ここまで鮮烈な赤色を表現できるというのは驚きです。
というわけで、iPad 2 からは飛躍的なスペックアップを果たしたものの、キーノートでの「従来機種より輝度・色域が25%向上」という発言には疑問が残ります。
画像比較
ご覧の通り、色の表現力が格段に向上しています。
True Tone 感想
iPad Pro の 9.7インチ版にかない "True Tone ディスプレイ" 機能は4つの環境光センサを使い、まわりの環境に合わせてディスプレイの明るさ・色温度を自動調整してくれる機能です。
我が家は各部屋・キッチン・玄関を 5000K (昼白色)、居間・洗面所を 3000K (電球色) にしていますが、iPad を持って各部屋を移動すると、目が環境に適応していくように明るさや色が「じわ〜」っと変化していきます。具体的には
- True Tone オフ : 6800K
- 昼白色(5000K) : 6200K
- 電球色(3000K) : 5800K
となり環境光に対して一見控えめな変化になっていますが、この繊細で絶妙な調整により自然な色合いを長時間楽しむことができます。
Night Shift 感想
iOS 9.3 で導入された "Night Shift" は、近年問題になっているブルーライトによる体内時計の狂い・睡眠障害に対するアップルの提案です。日の入りとともにディスプレイの色温度を下げ、ブルーライトをカットし良質な眠りに導くとのことです。
波長スペクトル [nm]
スペクトル測定の結果、Night Shift 機能により波長500nm以下のいわゆるブルーライト成分が大幅に軽減されていることがわかります。
iPad Pro 9.7" with Night Shift (電球環境下)
Night Shift は欧米の電球で優しく照らされたベッドルームでは違和感なく使えるのですが、青白い蛍光灯で部屋全体をピカピカに照らされた部屋では「いきなり液晶の色がおかしくなった。故障!?」と激しい違和感を感じるでしょう。ブルーライト大好きな日本ではヘタすると「尿液晶機能」などと罵られるかもしれませんね・・・。まあ、先進国向けの機能ですので、気にくわなければ使わなければ良いだけのことです。
私はベッドの照明を電球色のLEDにしているので活用していきたいと思います。また日の入り時間ではなく任意の時刻にも設定できるので、就寝時間にセットして「画面が暖色になったら寝なさい」というサインにするのもアリだと思います。
さいごに
今回、iPad 2 から iPad Pro 9.7" とタイムスリップを果たしたわけですが、2つの iPad を比べることで iPad Pro の完成度の高さ、そして同時に iPad 2 の完成度の高さも実感することができました。iPad 2 でアップルが示したタブレットのあり方は既に完成しており、iPad Pro ではそれを高め、より高品位で快適なユーザー体験を享受することができるようになりました。
「正直ほぼ寝モバ専用機だし、わざわざ Pro にすること無かったかなー」と思っていましたが、すべてがストレス無くキビキビ動き、画面はきれいで疲れにくく、内蔵スピーカーの音も格段によくなった。指を置くだけだけロックが解除できる Touch ID もものすごく便利。そして軽くて薄い(細い)と大満足な買い換えになりました。スペック不足でできなかった iOS版ドラゴンクエストXIII を購入しプレイする今日この頃です。
document control
- 2016/4/4 : 初版
- 2016/4/5 : データが不正確だったため再測定、波長スペクトルグラフを追加