日々之迷歩

世の中わからんことだらけ

ITが複雑で難しくなっていく様に翻弄される日々です。微力ながら共著させていただいた「シェル・ワンライナー160本ノック」をよろしくお願い申し上げます。

Haskell版Tukubaiコマンド

うっわ2年ブリブリの久々ブログ・・・はてなダイアリーからはてなブログに移行して初めてのエントリ。

昨年USP友の会に入会し、シェル芸本や勉強会でお世話になっております。 Open usp Tukubaiのコマンドは、日々のデータ処理やシステム管理に活用させてもらっております。

UEC - usp engineers' community - usp Tukubai github.com

さて、このコマンド群はPythonで書かれております。(商用版はCで書かれて超高速らしい) なのでそんなに高速じゃないです。大きなデータを扱うときは、ちょっとパフォーマンスが気になります。 特によく使うselfコマンドが・・・awkに比べるとかなり遅い。

ところでUSP友の会会長の上田さんが、シェルスクリプトマガジンで、Haskell版 Open usp Tukubai 完成させるぞ企画「Haskellでやってはいかんのか?」を連載されています。ということで、高速化が期待できるHaskell版を使えるようにしてみました。前提環境はMacで、OSX Yosemite、Homebrew。

まずはHaskellのビルド環境をインストール。

$ brew install ghc
$ brew install cabal-install

更にHaskellのモジュールを追加インストール。

$ cabal update
$ cabal install parsec
$ cabal install split
$ cabal install regex-posix
$ cabal install regex-compat

これでHaskellのビルド環境が出来ました。 次にOpen usp Tukubaiを適当な場所にgitで取得

$ git clone https://github.com/usp-engineers-community/Open-usp-Tukubai.git

そしてコンパイルします。

$ cd Open-usp-Tukubai/COMMANDS.HS
$ ls | head
calclock.hs
cgi-name.hs
check_need_name.hs
cjoin0.hs
cjoin1.hs
cjoin2.hs
comma.hs
count.hs
ctail.hs
dayslash.hs

$ \ls *.hs | sed 's/^/ghc /' | sh ###コンパイルのシェル芸
$ ls -l | head
total 242968
-rwxr-xr-x  1 papiro  staff  5632744  4  2 22:54 calclock*
-rw-r--r--  1 papiro  staff     2437  4  2 22:54 calclock.hi
-rw-r--r--  1 papiro  staff     4770  4  2 22:54 calclock.hs
-rw-r--r--  1 papiro  staff    34688  4  2 22:54 calclock.o
-rwxr-xr-x  1 papiro  staff  1442984  4  2 23:29 cgi-name*
-rw-r--r--  1 papiro  staff     1509  4  2 23:29 cgi-name.hi
-rw-r--r--  1 papiro  staff     3336  4  2 22:54 cgi-name.hs
-rw-r--r--  1 papiro  staff    27056  4  2 23:29 cgi-name.o
-rwxr-xr-x  1 papiro  staff  1430320  4  2 22:54 check_need_name*

さて、出来た実行ファイル群を、シェル芸で~/binとかに置きましょうか。 実行ファイルサイズが結構デカイので、stripも一応かけといた。

$ mkdir ~/bin
$ \ls | grep -v '\.' | xargs -I{} cp {} ~/bin
$ strip ~/bin/*

あとは、~/binをPATHの先頭にしておけば、Haskell版を優先的に使います。 Python版を使うときは/usr/local/bin/selfとか指定すればよろし。

$ grep PATH ~/.bash_profile
export PATH=~/bin/:$PATH

timeコマンドで計測してみたところ、self、count、sm2とかで2倍〜5倍くらい高速化な感じ。

さて、最後になりましたが、私自身はHaskell分かりません。関数型言語ってのも分かりません。 そもそもコンパイル型言語ほとんど出来ません・・・・