[linux]ncコマンドによるファイル転送

LAN内のlinux同士でファイル転送したいが、FTPやNFSのサーバ設定まではしたくない時がある。
ncコマンドを使うと簡単にファイルを転送できる。
ncはnetcat。ネットワーク越しにcatできるわけだ。

待ち受け側ではポート番号を指定して、プロセスを起動することによってサーバになる。

[java]Atomic*クラスのlazySetメソッド

JavaのAtomic*クラス群にlazySetというメソッドがあるけどなんだかよくわからなかった。ので、調べてみました。

APIリファレンスを見ても、
「指定された値に最終的に設定します。」
と書かれているだけで、通常のsetと何が違うのかよくわからない。

Java8 API仕様 http://docs.oracle.com/javase/jp/8/api/

以下に一応説明があるけど、結局どんな時に使うのか。。。

https://docs.oracle.com/javase/jp/8/api/java/util/concurrent/atomic/package-summary.html

結局、見つかったのはDoug Lea氏のコメント。

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6275329

もう他のスレッドが見る必要のない、削除されたオブジェクトにGCを促すためにnullを入れたいけど、
パフォーマンスのために同期したくないって時に使うみたい。
まあ、いつかnullが入ると。

[unix]lsofコマンド

あるファイルを延々となにかのプロセスが読み込んだり、書き込んだりしていて、その正体を知りたい時がある。 そんなときはlsofコマンドを使うのがいい。
例えば、以下のようにファイルを開いておいて

$ tail -f ~/some.log

別のシェルでlsofコマンドを使うと、こんな感じで表示される。

$ lsof ~/some.log
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
tail    3901 username  3r   REG    8,7      780 1976760 some.log

逆にコマンド名やプロセスIDを指定して、開いているファイルを表示することもできる。

# -cでコマンド名を指定
$ lsof -c tail
# -pでプロセスIDを指定
$ lsof -p 3901

[bash]シェルスクリプトのループ内でのリダイレクト

シェルスクリプトのループはあまり速くない。
なので、できるだけ速くさせるためにはリダイレクトの位置に気をつけたい。

これは遅い
for i in $( seq 100000 )
do
  echo $i >>loop.dat
done
手元の環境で1.027秒かかった。
これはどうだろうか。
for i in $( seq 100000 )
do
  echo $i
done >>loop.dat
先ほどと同じ環境で0.609秒となった。40%もの改善だ。
あらかじめ、execコマンドで標準出力の向き先を変えておくとどうだろうか?
exec 1>loop.dat
for i in $( seq 100000 )
do
  echo $i
done
こちらは0.610秒。ループ自体をリダイレクトするのとほぼ同じ結果となった。
まあ、今回のケースではループする必要なんてないんですが。。。
seq 100000 >loop.dat
#ちなみにこれは0.011秒で終わる!

というわけで、今回の教訓はシェルスクリプトでループは邪道。
じゃなくって、ループの中でリダイレクトするなってことでした。

[linux]システムコールの一覧

Linuxのシステムコールの一覧ってどこかにないかなと思ったんですが、man syscallsで見られるんですね。

$ man syscalls

同じような感じでCの標準ライブラリ関数の一覧って、見られないのかな。。。

[bash]ビルトインコマンドのヘルプ

プロセスの消費リソース表示 その1で2種類のtimeコマンドについて書いたけど、シェルのビルトインコマンドがどのようなオプションを受け付けるのかあまりよくわかってなかった。
manで調べると外部コマンドのtimeの情報が出てくる。

$ man time

調べてみたところbashのビルトインコマンドの説明はhelpで出てくるらしい。
例えばtimeの説明は以下のようになる。

$ help time
time: time [-p] pipeline
    Report time consumed by pipeline's execution.
    
    Execute PIPELINE and print a summary of the real time, user CPU time,
    and system CPU time spent executing PIPELINE when it terminates.
    
    Options:
      -p        print the timing summary in the portable Posix format
    
    The value of the TIMEFORMAT variable is used as the output format.
    
    Exit Status:
    The return status is the return status of PIPELINE.
times: times
    Display process times.
    
    Prints the accumulated user and system times for the shell and all of its
    child processes.
    
    Exit Status:
    Always succeeds.

これを見るとtimesというビルトインコマンドもあることがわかる。
面白いのはifやforといったシェルの制御構文もhelpで見られるところ。

$ help if
$ help for

シェルスクリプトを書いていて、ちょっと書き方を参照したいときにいちいちweb等で調べなくていいので便利。

[linux]プロセスの消費リソース表示 その2

その1では紹介したtimeコマンドの他にperfコマンドを使う方法がある。
※perfはシステムにデフォルトでは入っていないかもしれない。

perfはいくつかのサブコマンドから成り立っているけど、起動したプロセスの情報を単純に取得するにはstatを使うといい。

$ perf stat sort -r foo.txt

 Performance counter stats for 'sort -r foo.txt':

          1.880898 task-clock                #    0.569 CPUs utilized
               104 context-switches          #    0.055 M/sec
                 1 cpu-migrations            #    0.532 K/sec
               284 page-faults               #    0.151 M/sec
         2,905,110 cycles                    #    1.545 GHz
    stalled-cycles-frontend 
    stalled-cycles-backend  
         2,624,591 instructions              #    0.90  insns per cycle
           559,006 branches                  #  297.202 M/sec
            17,821 branch-misses             #    3.19% of all branches

       0.003305801 seconds time elapsed

また、下記のように-rオプションで実行回数を指定することもできる。

$ perf stat -r 5 sleep 1
 Performance counter stats for 'sleep 1' (5 runs):

          1.657008 task-clock                #    0.002 CPUs utilized            ( +-  3.25% )
                 2 context-switches          #    0.001 M/sec                    ( +- 20.79% )
                 0 cpu-migrations            #    0.121 K/sec                    ( +-100.00% )
               199 page-faults               #    0.120 M/sec
         1,338,609 cycles                    #    0.808 GHz                      ( +-  1.99% )
    stalled-cycles-frontend 
    stalled-cycles-backend  
         1,150,478 instructions              #    0.86  insns per cycle          ( +-  0.37% )
           233,825 branches                  #  141.113 M/sec                    ( +-  0.36% )
             9,804 branch-misses             #    4.19% of all branches          ( +-  1.32% )

       1.003059076 seconds time elapsed                                          ( +-  0.03% )

[linux]プロセスの消費リソース表示 その1

Linuxでプロセスの実行時間を計測するのによく使われるのはtimeコマンドだろう。
例えば、以下のようにすれば実際にコマンド実行に10秒かかり、sleepなのでプロセッサ時間をほとんど消費していないことがわかる。

$ time sleep 10

real    0m10.003s
user    0m0.002s
sys     0m0.001s

伝統的なUnixのtimeコマンドは秒までしか表示しないけど、秒以下が小数点3桁まで表示されているのはtimeがBashの組み込みコマンドでPOSIXよりも機能が拡張されているからだ。
試しにtypeでtimeを調べてみると以下のように表示される。

$ type time
time はシェルの予約語です

一方、whichでtimeコマンドを探すと以下となる。

$ which time
/usr/bin/time
※実際はLinuxのディストリビューションによってパスは違う可能性がある。

こっちのtimeはなんだろうか。

$ /usr/bin/time sort -r foo.txt
0.00user 0.00system 0:10.00elapsed 100%CPU (0avgtext+0avgdata 1028maxresident)k
0inputs+0outputs (0major+316minor)pagefaults 0swaps

こちらはGNU版のtimeコマンドでより詳細な情報を表示してくれる。
そのままだと表示が見やすいとは言えないが、-vオプションを付けるとさらに詳細な項目を並べて表示してくれる。

$ /usr/bin/time -v sort -r foo.txt

        Command being timed: "sort -r foo.txt"
        User time (seconds): 0.00
        System time (seconds): 0.00
        Percent of CPU this job got: 60%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 1024
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 317
        Voluntary context switches: 1
        Involuntary context switches: 105
        Swaps: 0
        File system inputs: 8
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

これでページフォールトの回数やIOの様子もお手軽に見ることができる。

※ちなみに1回めの-vなしのIO回数が0になっているのは-v付きを先にやってしまったためにfoo.txtがキャッシュに読み込まれてしまったからだと思う。。。
別のファイルで試したら、ちゃんと8inputsとかになった。

[C]LinuxでCプログラムの処理時間を計測する方法いくつか その3

移植性は低いかもしれないけど、最近のLinuxでは最もよさそうな関数が以下となる。
Linuxのバージョンや他のUnixシステムでは使えない可能性もある。

[clock_gettime関数]
#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespec *tp);

この関数ではその1、その2と違い、clk_id引数でどういった時間を取得するかを指定する。
よく使いそうなのは以下だろう。

CLOCK_MONOTONIC:ある時点からの単調増加のクロック数。NTP等の時間調整の影響を受ける。
CLOCK_MONOTONIC_RAW:ある時点からの単調増加のクロック数。NTP等の時間調整の影響を受けない。
CLOCK_PROCESS_CPUTIME_ID: CPU による高分解能のプロセス毎のタイマ。

timespec構造体は秒とナノ秒を保持している。

例:
    struct timespec start;
    struct timespec end;

    clock_gettime(CLOCK_MONOTONIC, &start);
    // 計測したい処理...
    clock_gettime(CLOCK_MONOTONIC, &end);

    long long elapsed = 1000 * 1000 * 1000 * (end.tv_sec - start.tv_sec);
    elapsed += end.tv_nsec - start.tv_nsec;

[getrusage関数]
#include <sys/time.h>
#include <sys/resource.h>
int getrusage(int who, struct rusage *usage);

こちらは時間だけでなく、リソースの使用状況を取得する関数となる。
who引数で何のリソースの使用状況を取得するかを指定する。
whoに指定する値は以下がある。

RUSAGE_SELF:プロセスの消費リソース。
RUSAGE_CHILDREN:子プロセスまで含めた消費リソース。
RUSAGE_THREAD:スレッドの消費リソース。

rusage構造体はユーザCPU使用時間やシステムCPU使用時間以外にも様々なリソースの使用状況を保持している。

例:
    struct rusage start;
    struct rusage end;
    int i;

    getrusage(RUSAGE_SELF, &start);
    // 計測したい処理...
    getrusage(RUSAGE_SELF, &end);

    long long elapsed = 1000 * 1000 * (end.ru_utime.tv_sec - start.ru_utime.tv_sec);
    elapsed += end.ru_utime.tv_usec - start.ru_utime.tv_usec;

その1、その2と同様に消費したリソース量を計測したいのか、実時間を計測したいのかによって使い分ける必要があるだろう。

[C]LinuxでCプログラムの処理時間を計測する方法いくつか その2

今回はPOSIXで決められている関数を使う方法。

[times関数]
#include <sys/times.h>
clock_t times(struct tms *buf);

times関数は引数bufにプロセスが消費したクロック数を格納する。
tms構造体はユーザ時間やシステム時間、子プロセスが消費した時間をフィールドとして持っている。

1秒あたりのクロック数は以下で求められる。
sysconf(_SC_CLK_TCK);

例:
    struct tms start;
    struct tms end;
    long elapsed;

    times(&start);
    // 計測したい処理...
    times(&end);

    elapsed = (long)(end.tms_utime - start.tms_utime);

[gettimeofday関数]
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

times関数がクロック数を取得するものであるのに対して、こちらはシステム時刻を取得する関数となる。
また、timeval構造体はマイクロ秒まで保持することができる。

例:
    struct timeval start;
    struct timeval end;
    struct timeval elapsed;
    long elapsedusec;

    gettimeofday(&start, NULL);
    // 計測したい処理...
    gettimeofday(&end, NULL);

    timersub(&end, &start, &elapsed);
    elapsedusec = 1000 * 1000 * elapsed.tv_sec + elapsed.tv_usec;

gettimeofdayはシステム時刻を返すため、計測中にシステム時刻が変更された場合は影響を受けてしまう。 また、timeval構造体はtimersubマクロで差分を取得することができる。

しかしながら、現在のLinuxでは今回紹介した関数よりもclock_gettimeの使用が推奨されているようだ。
http://linuxjm.osdn.jp/html/LDP_man-pages/man2/times.2.html
http://linuxjm.osdn.jp/html/LDP_man-pages/man2/gettimeofday.2.html

[C]LinuxでCプログラムの処理時間を計測する方法いくつか その1

LinuxのCプログラムで処理時間の計測をする場合にはいくつかの方法が考えられるけど、それぞれの違いがあまりよくわかってなかったので、どのような長所、短所があるか調べてみた。

大きく分けて、システム時刻を取得する方法とプロセスの消費CPU時間を取得する方法がある。
何を計測するのかによって、どちらを使うか決める必要があるだろう。

まずはANSI Cで決められている関数を使う方法。移植性は最も高い。

[time関数]
#include <time.h>
time_t time(time_t *t);

time関数は現在のシステム時刻を返す。
ただし、秒精度までしか求められない上に計測中にシステム時刻が変更された場合にはズレが生じてしまう。

例:
    time_t start;
    time_t end;
    long elapsed;

    time(&start);
    // 計測したい処理...
    time(&end);

    elapsed = (long)difftime(end, start);
移植性を考えれば、time_t型は直接引き算をするのではなく、difftimeを使ったほうがいいだろう。

[clock関数]
#include <time.h>
clock_t clock(void);

こちらはプロセスが使用したCPU時間を返す。
戻り値をCLOCKS_PER_SECで割れば、秒数に変換することもできる。
※CLOCKS_PER_SECはプロセッサの実際のクロック数の精度ではなく、C89,C99では1000000であることが要求されている。

例:
    clock_t start;
    clock_t end;
    long elapsed;
    long elapsedsec;

    start = clock();
    // 計測したい処理...
    end = clock();

    elapsed = (long)(end - start);
    elapsedsec = elapsed / CLOCKS_PER_SEC;

ただし、time関数と違い、sleep等でCPU時間を消費しない待機はカウントされないため、注意しよう。
※time_tとclock_tはlongとして定義されている処理系が多いけど、必ずしもそうではないので注意しよう。

DOT言語

クラス図などを書くときにはUMLのモデリングツールや、ソースコードからの自動生成ツールを使うことが多いと思うけど、DOT言語というのを使うとクラス図のようなグラフ図をテキストから生成できる。

Graphviz Documentation
http://www.graphviz.org/Documentation.php
DOTユーザーズガイド日本語訳
http://cbrc3.cbrc.jp/~tominaga/translations/index.html#dot

Doxygenでも図の生成にdotを使用している。
http://www.doxygen.jp/diagrams.html

例えば、以下のようなDOT言語のテキストをsample.dotという名前のファイルに保存して
digraph sample {
    node [ shape = box ];
    edge [ dir = back, arrowtail = onormal, arrowsize = 1.5 ];

    Collection [ label = "<<interface>>\nCollection" ];
    Set        [ label = "<<interface>>\nSet" ];
    SortedSet  [ label = "<<interface>>\nSortedSet" ];
    List       [ label = "<<interface>>\nList" ];
    Queue      [ label = "<<interface>>\nQueue" ];
    Map        [ label = "<<interface>>\nMap" ];
    SortedMap  [ label = "<<interface>>\nSortedMap" ];

    Collection -> Set -> SortedSet;
    Collection -> List;
    Collection -> Queue;
    Map -> SortedMap;

    { rank = same; Set; Map; }
}

dotコマンドに画像を生成させる。
この場合はGIF形式を生成しているけど、PNG,JPEG等、様々な形式に対応している。

$ dot -Tgif sample.dot -o sample.gif

すると以下のような画像が生成される。



ソースコード管理システムでのバージョン管理とも相性良さそうだし、ちょっとした図を書くときなんかに使えるんじゃないだろうか。

[awk]gawkとmawk

多くのLinuxディストリビューションではデフォルトのawkとしてgawkが採用されているけれども、Debian系ではデフォルトのawkとしてgawkではなく、mawkが採用されているようだ。
mawkってなにものだろうか?

http://invisible-island.net/mawk/

mawkはgawkのような高度な拡張機能は使えないけれども、その分高速に動作することを目標に作られている。
grep,egrep,fgrepみたいなもんか。

もし、awkが意図しているオプションを受け付けなかったりしたら、どのawkを使っているか確認するといい。
また、gawkを使っていてパフォーマンスを上げたい場合はmawkの使用を検討するといいかもしれない。

[Java]equalsメソッド実装時にテストすること

自分で作ったクラスにequalsメソッドを実装した場合、最低限以下の挙動はテストしておく必要がある。
  1. 反射律
    自分自身との同値比較は真となること。
    a.equals(a)は必ずtureになるということ。

  2. 対称律
    同値比較の左辺と右辺を入れ替えても比較結果は変わらないということ。
    a.equals(b)がtrueであれば、b.equals(a)もtrueとなるということ。
    falseの場合も同じ。

  3. 推移律
    a,bの同値比較結果とb,cの同値比較結果が同じであれば、a,cの同値比較結果も同じとなるということ。
    a.equals(b)がtrueでb.equals(c)がtrueであれば、a.equals(c)もtrueとなるということ。
    falseの場合も同じ。
これらについてはJava APIリファレンスのObjectクラスのequalsメソッドの項にも書かれている。

また、一般的にオブジェクトの中身に言及せずに、上記の3条件を満たしていることがオブジェクトの同値性の定義でもあるというところが面白い。

[python] switchもどき

ipythonにはswitch, case文はありません。
breakの書き忘れで変なバグを生まないように…だとか。
でも、if, elifを重ねるのって嫌ですよね。
特に同一変数の評価をif, elifで書くとなんだか非効率な気もする…

そこで、こんな書き方。

n = 0
x = 100
val = {
 0: lambda x: x + 1,
 1: lambda x: x + 2,
 2: lambda x: x + 3
}.get(n)(x)
print val # 101

ちょっとわかりにくい気もしますが、
イディオムとして覚えてしまえば、switch, caseとさほど変わらないです♪


[python] difflibを使ってみる

pythonには、標準でdifflibというモジュールが含まれています。

いわゆる、linuxのdiff相当のことができます。

import difflib
a = '''
abc
def
ghi
'''
b = '''
abc
ddf
ghi
'''
list_a = a.splitlines()
list_b = b.splitlines()
print list_a  # ['', 'abc', 'def', 'ghi' ]
print list_b # ['', 'abc', 'ddf', 'ghi' ]
for line in difflib.unified_diff(a, b):
      print line

result:
@@ -1,4 +1,4 @@
 abc
-def
+ddf
 ghi

diff -uと同じような出力を得られます。

[Java]Java7からはヨーダ記法はイディオムではなくなった?

ヨーダ記法というのがある。オブジェクト(特に文字列)を比較する際にnullチェックを省略するために対象のオブジェクトではなく、リテラルの方のequalsメソッドを使う手法だ。

String jedi;
...
if ("Yoda".equals(jedi)) 
...
確かにこれならstrがnullでもNullPointerExceptionが発生しないし、条件分岐はfalse側に行く。

なんだけど、Java7からはObjectsクラスが導入された。
Objectsメソッドにはstaticメソッドとしてequlasメソッドが存在するので、こちらを使うほうが今後のイディオムになるかもしれない。

boolean Objects::equals(Object a, Object b)

このメソッドはaとbのどちらかがnullの場合はfalseを返し、両方がnullの場合はtrueを返す。両方ともnullではない場合はa.equals(b)の結果が返される。
Objectsメソッドにはequalsメソッド以外にもオブジェクト比較やnullチェックに便利なメソッドがあるので、Java7以降でコードを書く場合は使ってみるといいかもしれない。

ちなみになぜヨーダ記法なんて呼ばれているかというと。。。
スターウォーズのヨーダが通常の英語とは違う語順でしゃべるからだそうです。

[シェルスクリプト]ランダムな数値

シェルスクリプトでランダムな数値を得る必要があったのでちょっと調べてみました。

bashならRANDOM変数が使える。
例えば0から9の整数をランダムに得たければ、以下のようにする。

$ echo $(($RANDOM % 10))

$RANDOMは0から32767までの整数を返すから、お手軽にやりたければこれでもいい。
だけど、bash以外のシェルを使う場合や、乱数を複数得たい場合は/dev/urandomを使うほうがよさそう。
試しに以下を実行すると画面にバイナリのデータが延々と表示される。

$ cat /dev/urandom

Linuxの/dev/urandomを読み込むと擬似乱数ビット列が生成されるため、このような表示になる。
これを数字文字列に変えるにはodコマンドを使う。

$ od -vAn --width=4 -tu4 </dev/urandom

-vAnは出力表示のオプション。
-vを指定しないと直前の行と同じデータはアスタリスクで出力されてしまう。
-Anは入力データのオフセットの表示を抑止する。

--width=4も出力表示のオプションだけど、1行が何バイトかを指定する。
※なぜか短縮形式の-wは推奨されないと書いてある。
http://linuxjm.osdn.jp/html/gnumaniak/man1/od.1.html

-tu4は出力フォーマットを指定している。この場合は符号なし4バイト整数を指定している。

ただし、このままでは延々と数字が表示され続けるので、-Nオプションで何バイトで終了するかを指定する。

$ od -vAn --width=4 -tu4 -N40 </dev/urandom

この場合4x10で10行出力された時点で終了する。
もちろん1行だけ必要な場合は-N4とする。

$ od -vAn --width=4 -tu4 -N4 </dev/urandom

これを0から9等に制限したければ、以下のようにawkで処理すればいい。

$ od -vAn --width=4 -tu4 -N4 </dev/urandom | awk '{ print $1 % 10 }'

参考Webサイト
シェルやシェルスクリプトで乱数を使う2つの方法

[JavaScript] 文字列結合の速さ

どんな言語でもよく使う文字列結合。

+演算子を使って結合する方法と、配列に入れてからjoinする方法
どちらが速いのか実験してみました。
var n = 1000000
  , s = 'abc'
  , str = ''
  , arr = []
  , arr2 = []
  , i;

console.log('試行回数 :' + n);

console.time(' + ');
for (i = 0; i < n; i++) {
 // +演算子で文字列結合
  str += s;
}
console.timeEnd(' + ');

console.time(' join ');
for (i = 0; i < n; i++) {
  // 配列に追加(push)
  arr.push(s);
}
// 文字列化
arr.join('');
console.timeEnd(' join ');

console.time(' index ');
for (i = 0; i < n; i++) {
  // 配列に追加(index指定)
  arr[i] = s;
}
// 文字列化
arr.join('');
console.timeEnd(' index ');
結果
(n=1000000)の場合FireFox(38)Chrome(43)IE(11)
+演算子7~140ms80ms400ms
push/join30ms230ms450~500ms
index/join22ms40ms280ms

(n=10)の場合FireFox(38)Chrome(43)IE(11)
+演算子0.40ms0.10ms0.10~0.15ms
push/join0.30ms0.05ms0.10~0.15ms
index/join0.20ms0.03ms0.10ms

どの値も、実行するたびに上下しますが大体こんな感じでした。
この結果を見ると、joinを使ったほうが速そうです。
ただ、pushを使っているとブラウザによっては時間がかかるようなので
index指定を使ったほうが安心ですね。

[JavaScript]整数の最大値

JavaScriptで整数をインクリメントしていくと、あるところでそれ以上大きくならなくなる。

for (let i = 0; i < veryLargeNumber; i++) {
     ...
}
...
9007199254740989
9007199254740990
9007199254740991
9007199254740992
9007199254740992
9007199254740992
9007199254740992
...


9007199254740992をインクリメントしても9007199254740992になってしまう。
JavaScriptのNumber型は64bitの倍精度浮動小数点型で表現されるので、整数を正確に表せるのは仮数部の53bit分ということになる。

16進数で書くとこんな。
0x1FFFFFFFFFFFFF
9007199254740991(10進)

だから、9007199254740991を超えると整数の値が不正確なものになってしまう。
試しに以下を実行して、10進表現と2進表現を表示すると

for (let i = 0; i < 10; i++) {
    print(0x1FFFFFFFFFFFFF + i + ': ' + (0x1FFFFFFFFFFFFF + i).toString(2));
}


9007199254740991: 11111111111111111111111111111111111111111111111111111
9007199254740992: 100000000000000000000000000000000000000000000000000000
9007199254740992: 100000000000000000000000000000000000000000000000000000
9007199254740994: 100000000000000000000000000000000000000000000000000010
9007199254740996: 100000000000000000000000000000000000000000000000000100
9007199254740996: 100000000000000000000000000000000000000000000000000100
9007199254740996: 100000000000000000000000000000000000000000000000000100
9007199254740998: 100000000000000000000000000000000000000000000000000110
9007199254741000: 100000000000000000000000000000000000000000000000001000
9007199254741000: 100000000000000000000000000000000000000000000000001000



9007199254740992が2回現れたり、9007199254740996が3回現れたりするけど、9007199254740993や9007199254740995というのは現れない。
これは仮数部の端数処理が2進数の再近接偶数丸めで行われているからだ。端数は最も近い表現可能な数に丸められるけど、上下の表現可能な数から等距離の場合、丸め後の値が偶数になるように丸められる。
その結果、以下の矢印の方向にまるめられ、9007199254740992が2回出現し、9007199254740996が3回出現することになる。

9007199254740992: 10000000000000000000000000000000000000000000000000000 0
9007199254740993: 10000000000000000000000000000000000000000000000000000 1↓
9007199254740994: 10000000000000000000000000000000000000000000000000001 0
9007199254740995: 10000000000000000000000000000000000000000000000000001 1↑
9007199254740996: 10000000000000000000000000000000000000000000000000010 0
9007199254740997: 10000000000000000000000000000000000000000000000000010 1↓
9007199254740998: 10000000000000000000000000000000000000000000000000011 0

[python] SyntaxError. Non-ASCII character

タイトルのエラーが出たら、
文字のエンコードの問題。

ファイルの先頭に
# coding: utf-8
と書くと回避できる。
coding:のgと:の間に空白があるとダメ。:とutf-8のuの間は空いてもオッケー。

界隈では、-*- coding: utf-8 -*-なんて書き方をよく見かける。emacs流らしい。

[python] 辞書のループ

いつも忘れるので、メモっておこう

dic = { 'name': 'Mizu.A',  'age': 33 }
for k, v in dic.iteritems():
   print k + '=' + str(v)

result:
age = 33
name = Mizu.A

JavaScriptのループ その3

[その1]では以下のようなループで変数iのスコープで関数全体になってしまうと書いた。
これはJavaScriptでは変数にブロックスコープがなく、var変数はどこで宣言しても関数の先頭で宣言したのと同じように扱われてしまうからだ。
※ちなみに変数宣言が関数の先頭に移動してしまう挙動をホイスティング(巻き上げ)と呼ぶ。
for (var i = 0; i < 5; i++) {
    ...
}
print(i);
出力結果は以下となる。

5

ECMAScript6をサポートしている環境ではvarではなくletキーワードが使える。
for (let i = 0; i < 5; i++) {
   ...
}
print(i);
let変数はブロック変数となるため、出力結果は以下となる。

ReferenceError: i is not defined

JavaScriptのループ その2

前回はJavaScriptで配列のループをする場合はCスタイルのループを使うようにした。
ECMAScript5thをサポートしている最近のブラウザでは配列のメソッドとしてforEachが使える。
こんな感じ
[ 31, 45, 52 ].forEach(function(e) { print(e); });
出力:
31
45
52

forEachのいいところはその1であったfor inのように配列の要素とは関係のないプロパティを列挙しないところ。

JavaScriptのループ その1

JavaScriptで配列をループするときには for in ループは使えない。
例えば、以下のような場合は要素ではなく、インデックスがとり出されてしまう。
# print関数が引数を文字列で出力するとして。
var a = [ 1, 2, 3, 4, 5 ];

for (var e in a) {
  print(e);
}
出力:
0
1
2
3
4

これはJavaScriptの for in ループは配列の要素ではなく、オブジェクトのプロパティを列挙するためのものだからだ。
だから、以下のようにすれば、配列の要素以外のものもとり出されてしまう。
var a = [ 1, 2, 3, 4, 5 ];

a.foo = 'bar';  // どこかでプロパティを設定

for (var e in a) {
  print(e);
}
出力:
0
1
2
3
4
foo

だから、JavaScriptで配列をループしたい場合は素直にこう書く。
var a = [ 1, 2, 3, 4, 5 ];

for (var i = 0, l = a.length; i < l; i++) {
  print(a[i]);
}

でも、インデックスとして使っている変数iのスコープはこのループが存在する関数全体になってしまうという問題が残る。

null許容コレクションと不許容コレクション

Javaのコレクション型の中には要素(Mapの場合はキーも)としてnullを許容するものと許容しないものがある。例えばHashMapはキーと値にnullを許容するけど、TreeMapはキーとしてnullを許容しない。

なんでこんなことになっているかというとTreeMapは要素をソートするためにキーの値を見る必要があるからだろう。普通はソートするためにnullと比較することは出来ないからだ。
逆に言えば、TreeMapはコンストラクタにnull許容なComparatorを渡せば、キーとしてnullが扱えるようになる。

つまり一般的には要素の属性を利用するものはnull不許容で、要素の属性を利用しないものはnull許容と考えればいい。

Javaで空のリストを返す

メソッドからコレクションを返す場合、無効な状態を表すのにnullを返すのではなく、要素数0のコレクションを返すのが良い作法とされている。
でも、その度に新しいインスタンスを作成するのは無駄なようにも思える。
そういう場合はjava.util.CollectionsクラスのemptyListメソッドで空のListインスタンスを取得する方法がある。

if (apple.equals(orange)) {
    return Collections.emptyList();
}

emptyList以外にもemptyMap等あるので、使いたいコレクション型に合わせて、メソッドを呼べばいい。

気をつけなくちゃいけないのはemptyListで返されるListは変更不可能ということだ。
あくまで読み取り用のコレクションを返す場合に使える方法だ。
以下のようにemptyListで取得したListに要素を追加しようとすると例外が発生する。

List<String> strs = Collections.emptyList();
strs.add("orange");
Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.TreeMap.compare(TreeMap.java:1290)
        at java.util.TreeMap.put(TreeMap.java:538)
...

Javaでのraw型の警告対処

Javaで古いソースコードの改修をするときにジェネリクスを使っていないraw型のコレクションを取り扱わなければいけない時がある。
まるごとリファクタリングできればいいんだけど、外部ライブラリになっていていじれない場合は警告を抑制する必要がある。

例えば、以下のようにraw型のListを返してくるメソッドがあったとしよう。
List getList()

これを使って以下のようなコードを書くと
List<String> ls = getList();
このメソッドを使おうとするとコンパイラによって警告が出力される。

警告: [unchecked] 無検査変換

これを防ぐためにはSuppressWarningsアノテーションをつける。
今回の場合は無検査変換なので"uncheked"。

@SuppressWarnings("unchecked")
List<String> s = getList();
アノテーションは変数宣言やメソッドなどにつけることができるけど、getListメソッドを呼ぶ度につけるのはめんどうだし、見た目も良くない。

そこで以下のようなラッパーメソッドを用意する。

@SuppressWarnings("unchecked")
public <T> List<T> getTypedList() {
    return legacyObj.getList();
}
これでSuppressWarningsを書くのは1箇所で済む。

シェルスクリプトはどうやって自分自身のファイル名を拾うか

前回はシェルスクリプトから数値計算するのにbcを使ったけど、 数値計算用のスクリプト言語としてcalcというのがある。
プログラミング言語として面白い特徴がいくつかあったので書いてみる。

オプションとして-fフラグというフラグがある。
このフラグは #!/usr/bin/calc のようにシェバンでcalcを実行する場合に指定し、しかもオプションの中でも最後に指定しろ、となっている。

なぜこんなことになっているかというとシェバンが書かれているファイルのファイル名がほしいから。

通常、unixのシェルからコマンドを呼び出すとシステムがexecシステムコール呼び出し時に引数リストの先頭に呼び出されたコマンドのパスを付加する。

試しにCで以下のようなプログラムを書いて、実行ファイル名をshbangとしてみると

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("%d\n", argc);
    printf("%s\n", argv[argc - 1]);

    return 0;
}

$ ./shbang
1
./shbang

しかし、以下のようにシェルスクリプトのシェバンを通じて呼び出されると

$ cat shbang.sh
#!/path/to/shbang
$ ./shbang.sh
2
./shbang.sh

つまりこれは結果としてシェルから以下のコマンドを実行したのと等しい。

$ /path/to/shbang ./shbang.sh

通常、perlやrubyのようなスクリプトを実行するときはコマンドライン引数の最後で実行するファイル名を指定するけど、シェバンを使って起動されたときは起動された自分自身のファイル名が自動的に付加されているので、ファイル名を指定したのと同じ効果があるわけだ。

あ、この話って別にcalcの話じゃないですね。

Bashのプロセス置換で並列実行 & 待ち合わせ

シェルスクリプトで時間のかかる処理を並列で実行したい。
さらに各実行結果を取り出して順に並べるのにはBashのプロセス置換を使うと便利。

プロセス置換というのは本来ファイル名を書くところに一連のコマンドを記述できる機能。

<( command list... )
でcommand list...の結果をファイルのように読み込み、

>( command list... )
でcommand list...にファイルのように渡すことができる。

例えば、円周率を求めるのに高野の公式の4項を並列で計算して
最後に各項の和を求める処理は以下のような感じ(計算本体はbcで実行)。


#!/bin/bash
cat <(echo 'print sum(1/49,         -(49^2)),  "*48+"'  | bc -q pi10000.bc) \
    <(echo 'print sum(1/57,         -(57^2)), "*128-"'  | bc -q pi10000.bc) \
    <(echo 'print sum(1/239,       -(239^2)),  "*20+"'  | bc -q pi10000.bc) \
    <(echo 'print sum(1/110443, -(110443^2)),  "*48\n"' | bc -q pi10000.bc) | bc -q

pi10000.bc
scale = 10005;

define sum(t, c) {
  auto n, s

  for (n = 1; t != 0; n += 2) {
    s += t / n
    t /= c
  }

  return s
}
[参考:高野の公式]
http://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%81%E3%83%B3%E3%81%AE%E5%85%AC%E5%BC%8F

このように一時ファイルを使わずにパイプのように使える。
プロセス置換はkshやzshでも使えるみたい。

Cでcompareが-1,0,1を返す理由

JavaのAPIリファレンスでBigDecimalのcompareToを見ていて気づいたのだけれど、
BigDecimalの値の大小を比較する際には以下のように行えとある。
BigDecimal bd = ...

...

// bd > 1
if (bd.compareTo(BigDecimal.ONE) > 0) {

// bd == 1
} else if (bc.compareTo(BigDecimal.ONE) == 0) {

// bd < 1
} else if (bc.compareTo(BigDecimal.ONE) < 0) {

...

特に驚くようなこともないけれど、一歩引いて考えてみると
記法としてはとても巧妙なものだと気づく。
つまり、右辺を0にすると比較演算子がそのままcompareToの比較関係を表しているのだ。
演算子オーバーロードに似ていると言ったら言いすぎだろうか。

Cでstrcmpやmemcmpが-1,0,1を返すのはまあそんなもんかなくらいに思っていたけど、
なんだか理由がわかった気がする。

Javaでfinal変数が呼ぶ側に埋め込まれる理由

このタイトルはあまり正確じゃない。
正確にはfinal宣言と同時に値が定義された変数である。
Javaではfinal宣言と同時に値が定義されるかされないかで変数の挙動が変わってくる。
たとえば、
class A {
    public static final int a = 12345;
    public static final int b;

    static {
        b = 67890;
    }
}
上記のような場合、aはコンパイル時に値が決定する。これがいわゆる"定数(constant)"でbの場合は実行時にstaticイニシャライザが実行されるまで値が決定されない。
これはいわゆる一度だけ初期化可能な変数(readonly)だ。

ここまでは問題ないし、次もJavaプログラマならよく知っているだろう。

class B {
    public int addA() {
        return A.a + A.b;
    }
}
この場合、A.aはクラスBに埋め込まれてしまう。そのため、aの値を変更した場合、クラスAだけでなく、A.aを参照しているクラス、この場合はクラスBまで再コンパイルが必要となる。
これを嫌ってbのように宣言と同時に初期化せずにstaticイニシャライザで初期化しているコードもある。

なぜ、こんな仕様になっているんだろうか?
参照している側に埋め込まずに実行時にクラスAに参照しにいく仕様ではダメだったのだろうか?
パフォーマンスの問題だろうか?

結論を言ってしまえば、switch文である。
switch (x) {
    case A.a :
        ...
}
は問題ないけど
switch (x) {
    case A.b :
        ...
}
はコンパイルエラーになってしまうのだ。

これはなぜか?
まず、コンパイル時、実行時ともにcaseの値が重複しないことが保証されなければならない。
また、Javaのswitch文はJVMのlookupswitchかtableswitchバイトコードにコンパイルされるけど、Javaに限らず、通常switch-caseではジャンプテーブルが生成されることが多い。
この場合もcaseの値がコンパイル時と実行時で異なってしまうと都合が悪い。

そんな訳で定数は参照しているクラスに埋め込まれてしまうのだ。

javac -Xlint

普段はEclipseとかIDEを使っている人も多いと思うけど、javacコマンドでコンパイルするときに警告を最大限出してほしかったりする。
OracleのJDKであればjavacに-Xlintオプションを付けることによって、警告が出力される。

正規表現のデバッグ

正規表現も複雑になってくるとデバッガでステップ実行のようなことをしたくなってくることがある。
そんなときはPerlのデバッガを使うといい。

perlの起動時にオプションとして-Mre=debugもしくは-Mre=debugcolorを付けると
実行時に生成された正規表現オブジェクトの内容とマッチング経過が表示される。

例えば、"[tD]o\sBe\sDo"という正規表現を"to Be is to Do to Do is to Be Do Be Do Be Do"に適用すると
以下のように出力される。

$ perl -Mre=debug -e 'qq/to Be is to Do to Do is to Be Do Be Do Be Do/ =~ /[tD]o\sBe\sDo/'

Compiling REx "[tD]o\sBe\sDo"
Final program:
   1: ANYOF[Dt][] (12)
  12: EXACT <o> (14)
  14: POSIXD[\s] (15)
  15: EXACT <Be> (17)
  17: POSIXD[\s] (18)
  18: EXACT <Do> (20)
  20: END (0)
anchored "Be" at 3 (checking anchored) stclass ANYOF[Dt][] minlen 8 
Guessing start of match in sv for REx "[tD]o\sBe\sDo" against "to Be is to Do to Do is to Be Do Be Do Be Do"
Found anchored substr "Be" at offset 3...
start_shift: 3 check_at: 3 s: 0 endpos: 1 checked_upto: 0
Does not contradict STCLASS...
Guessed: match at offset 0
Matching REx "[tD]o\sBe\sDo" against "to Be is to Do to Do is to Be Do Be Do Be Do"
   0 <> <to Be is t>         |  1:ANYOF[Dt][](12)
   1 <t> <o Be is to>        | 12:EXACT <o>(14)
   2 <to> < Be is to >       | 14:POSIXD[\s](15)
   3 <to > <Be is to D>      | 15:EXACT <Be>(17)
   5 <to Be> < is to Do >    | 17:POSIXD[\s](18)
   6 <o Be > <is to Do t>    | 18:EXACT <Do>(20)
                                  failed...
  24 <o is > <to Be Do B>    |  1:ANYOF[Dt][](12)
  25 < is t> <o Be Do Be>    | 12:EXACT <o>(14)
  26 <is to> < Be Do Be >    | 14:POSIXD[\s](15)
  27 <s to > <Be Do Be D>    | 15:EXACT <Be>(17)
  29 <to Be> < Do Be Do >    | 17:POSIXD[\s](18)
  30 <o Be > <Do Be Do B>    | 18:EXACT <Do>(20)
  32 <Be Do> < Be Do Be >    | 20:END(0)
Match successful!
Freeing REx: "[tD]o\sBe\sDo"

出力内容の1〜9行目はコンパイルされた正規表現オブジェクトがどのような
10行目以降は実際に文字列に対してマッチングをしていく経過を表している。
ステップ実行とまではいかないが、十分なトレース情報が出力されている。
まず"Be"を検索しにいき(12行目)、そこから3文字戻り、マッチングを続けるが(11〜22行目)、
一度失敗し(23行目)、再度24文字目からマッチングを実行し(24〜30行目)、
マッチングに成功している(31行目)ことがわかる。

あくまで、Perlの実行時の動作なため、別の言語/処理系で同じ動作になる保証はないが、
別の処理系の動作のヒント程度にはなるのではないだろうか。

JDBC 4.0の例外

JDBC 4.0からは以下のSQL例外が追加されている。
SQLRecoverableException
SQLTransientException

SQLRecoverableExceptionはDBとのコネクションを一度クローズして再取得すれば、回復できる可能性がある例外。

SQLTransientExceptionは同じ処理を再実行すれば、回復できる可能性がある例外。

これらをうまくハンドリングすれば即時異常終了とリトライ処理を使い分けることができそうだ。

Javaの文字列結合パフォーマンス その2

さて、以下のようなコードではどちらのほうが処理が速くなるだろうか。

1. +演算子で結合
String s = s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;

2. StringBuilderで結合
StringBuilder sb = new StringBuilder();
sb.append(s1);
sb.append(s2);
sb.append(s3);
sb.append(s4);
sb.append(s5);
sb.append(s6);
sb.append(s7);
sb.append(s8);
sb.append(s9);
String s = sb.toString();

Core i5 1.6GHz環境で実行したところ、1m秒あたりの処理回数は以下となった。

1. +演算子で結合
15000 ops/msec
2. StringBuilderで結合
 7000 ops/msec

+演算子のほうが倍以上速いことになる。
なぜ、このような差が出てしまったのだろうか。
String s = s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
をコンパイルした結果を擬似的にJavaのコードで表すと以下になる。
String s = (new StringBuilder()).append(s1).append(s2).append(s3)
                                .append(s4).append(s5).append(s6)
                                .append(s7).append(s8).append(s9)
                                .toString();
これと2. StringBuilderで結合との違いはsb変数がappendメソッド呼び出し時にいちいち登場しないところにある。
これはappendメソッドが戻り値として、呼び出し先のオブジェクト参照を返すことをうまく利用している。
毎回、sb変数を参照する場合、 メソッド呼び出しを実行する前にオペランドスタックに毎回、sb変数をプッシュする必要が生じてしまう。

というわけで以下の書き方をすると、+演算子で結合した場合と同じ処理速度になる。

3. StringBuilderで結合改良
StringBuilder sb = new StringBuilder();
sb.append(s1)
  .append(s2)
  .append(s3)
  .append(s4)
  .append(s5)
  .append(s6)
  .append(s7)
  .append(s8)
  .append(s9);
String s = sb.toString();

処理速度とコードの見通しを考えると+演算子で結合したほうがよさそうだ。

Javaの文字列結合パフォーマンス その1

よくJavaでは文字列結合で+演算子より、StringBuilderを使ったほうがパフォーマンスがいいと言われるけれど、それはこういうケースだろう。
String s = "";
for (String e : stringList) {
    s += e;
}
ループ中で文字列を次々に連結させていく操作だ。
この場合はループの外でStringBuilderインスタンスを一度だけ生成して使ったほうが効率がいい。
StringBuilder sb = new StringBuilder();
for (String e : stringList) {
    sb.append(e);
}
String s = sb.toString();
ちなみにJava8ではStringにjoinメソッドが追加されたので、そちらを使うのが便利。

しかしながら、定数文字列と変数から文字列を作り出す場合にも同じようにStringBuilderを使っているケースが見られる。
StringBuilder sb = new StringBuilder();
sb.append("Hello, ");
sb.append(name);
sb.append("!");
String s = sb.toString();
この場合は+演算子で結合したほうが見た目はわかりやすい。
String s = "Hello, " + name + "!";
しかし、パフォーマンス的にはStringBuilderでappendしたほうが速い...のだろうか?

シェルスクリプトで複数データを一括UPDATEする

さて、どうして"行区切りのデータを適当な行数でまとめる"なんてことがしたかったというと
シェルスクリプトでRDBのデータを複数行更新する必要があったから。

11111
22222
33333
44444
...

のようなデータがあった時にこれらをキーにステータスを更新したいとしよう。

UPDATE Foo
   SET Status = '3'
 WHERE ID = '11111';

このUPDATE文を行数分発行するのはあまりやりたくないだろう。
なので、こうする。

UPDATE Foo
   SET Status = '3'
 WHERE ID IN('11111', '22222', '33333');

この時に元のデータから '11111', '22222', '33333' という文字列を作りたかったのだ。

実際にはSQL文の長さ上限とか、コミットサイズとかの制限があるので、
適当なデータ数を決めて、UPDATE文を作成すればいい。

行区切りのデータを適当な行数でまとめる

文で説明しようとすると難しいけど、

$ cat paste.dat
1
2
3
4
5
6
7
8
9

のようなデータがあった時に

1,2,3
4,5,6
7,8,9

にしたい。
これはpasteコマンドを使う。

$ paste -d ',' - - - < paste.dat | sed -e 's/,*$//'

なんでpasteコマンドでこんなことができるかというと
引数として-(ハイフン)を渡すと標準入力から読み込むから。
しかも、-(ハイフン)を書いた回数分、標準入力から読み込むので、
1行目、2行目、3行目を別に読み込んで、くっつけてくれる。

最後にちょうど3の倍数行で終わらなかった場合のために行末の,(カンマ)を削除する。

前回の文字列を繰り返す方法と組み合わせると以下のようになる。

$ paste -d ',' $(printf "%3s" | sed -e 's/ / -/g') < past.dat | sed -e 's/,*$//'

これなら100行毎とかでも対応できる。

シェルで文字列を繰り返す

シェルスクリプトでループを書くのはあまりかっこよくないなと。
ポイントはprintfでスペースを繰り返すところ。

$ printf "%3s" | sed -e 's/ /foo/g'
foofoofoo