とりとめのないことを書いております。
by tempurature
カテゴリ
全体
プログラミング
scheme
verilog
未分類
以前の記事
2016年 04月
2016年 03月
2016年 02月
2016年 01月
2015年 12月
2015年 11月
2015年 10月
2015年 09月
2015年 08月
2015年 07月
2015年 06月
2015年 03月
お気に入りブログ
PHPで競技プログラミング
メモ帳
最新のトラックバック
ライフログ
検索
タグ
人気ジャンル
ブログパーツ
最新の記事
情報処理技術者試験 お疲れ様..
at 2016-04-17 18:55
基本情報技術者試験 平成27..
at 2016-04-14 04:48
基本情報技術者試験 平成27..
at 2016-04-13 23:03
苦い薬(ハーブ、サプリメント..
at 2016-04-09 14:03
「おバカ度チェックリスト」を..
at 2016-03-24 09:54
外部リンク
ファン
記事ランキング
ブログジャンル
画像一覧
タグ:sed ( 1 ) タグの人気記事
exciteブログ用にソースコードを整形するスクリプト
以前sedで作ったソースコード整形スクリプトをperl, awk, racketでも作ってみました。

<github>

$ wc *
19 36 275 decorate.awk
17 36 305 decorate.pl
37 78 704 decorate.rkts
12 32 221 decorate.sh
31 77 739 decorate2.rkts
116 259 2244 合計

1行ずつ置換するだけであればsedが12行で一番コード効率が高いことがわかります。

次点として、LLであるperlが17行、awkが19行と言った感じでした。
pythonだともう少し短くできるか検討しましたが、やることが単純すぎるので、perlとさして変わらないだろうと感じました。

racketでも2パターン書いてみましたが、それぞれ37行, 31行といった感じでsedやLL言語に比べてコード効率が劣ってしまいました。perlでいうところのwhile (<STDIN>)イディオムと、破壊的代入をせずに順次処理を簡素化するイディオムを手続きとして別途記述する必要があったためです。あと標準入出力と文字列処理のライブラリがLL言語に比べていけてないということもあるのかもしれません。


これらの試みをした理由の一つとしては、sed+pipeの組み合わせでもっと重い処理をさせたとき、プロセスを一度にたくさん立ち上げることのボトルネックが見えてきたので、それを順次処理に置き換えられないかということでした。

<pipeの正しい使い方:プロセス生成時間が見えない>
cat [input-file] \
| (重い処理1) \
| (重い処理2) \
| (重い処理3) \
| cat

<pipeの間違った使い方:プロセス生成時間が効いてくる>
cat [input-file] \
| (軽い処理1) \
...
| (軽い処理1000) \
| cat

その意味で、perlを使えばあまりコード効率を下げずにプロセスを使わないスクリプトが書けるということが分かりました。awkも不慣れながら書いてみましたが、文字列の区切りとしてシングルクオート(')が使えないなど、古いだけあって洗練されてない感じがありました。


racketをperlの代わりに使った時にメリットはあるかということですが、racketを起動するコストはDrRacketほどではありませんが0.3秒ほどで、perlなどとは比べ物にならない遅さでした。また、racoでコンパイルしてから実行してもperlほどには速くなりませんでしたが、体感速度は上がりました。

$ time (decorate.sh tmp.txt > tmp)
( decorate.sh tmp.txt > tmp; ) 0.01s user 0.03s system 85% cpu 0.053 total
$ time (cat tmp.txt | decorate.pl > tmp)
( cat tmp.txt | decorate.pl > tmp; ) 0.03s user 0.00s system 120% cpu 0.025 total
$ time (cat tmp.txt | decorate.awk > tmp)
( cat tmp.txt | decorate.awk > tmp; ) 0.01s user 0.00s system 50% cpu 0.030 total
$ time (cat tmp.txt | decorate.rkts > tmp)
( cat tmp.txt | decorate.rkts > tmp; ) 0.00s user 0.01s system 4% cpu 0.328 total
$ time (cat tmp.txt | decorate2.rkts > tmp)
( cat tmp.txt | decorate2.rkts > tmp; ) 0.00s user 0.03s system 8% cpu 0.343 total
$ raco exe decorate.rkts
$ raco exe decorate2.rkts
$ time (cat tmp.txt | decorate.exe > tmp)
( cat tmp.txt | decorate.exe > tmp; ) 0.00s user 0.01s system 7% cpu 0.188 total
$ time (cat tmp.txt | decorate2.exe > tmp)
( cat tmp.txt | decorate2.exe > tmp; ) 0.01s user 0.01s system 16% cpu 0.180 total

racketの場合、LL言語のイディオムには乏しかったのですが、10行程でそれらの文法を記述できたのでプログラムの規模が大きい場合は得しそうな気はします。

ただし、文法やイディオムによる制約が緩いので、その分可読性を落としている気がします。つまり、読むコード読むコード構造が違うという感じです。


[PR]
by tempurature | 2015-09-21 01:21 | プログラミング