どう書くにまた投げた:コード中の文字の頻度分析

http://ja.doukaku.org/comment/6822/
入出力のバッファリングが必要なサイズの処理に行き当たったのは、いい経験だった。
binary_to_listを実行すると、いきなりすごい量のheap領域を確保しようとしてメモリ不足で死んだりもした。そこで、40KBぐらいをバイナリデータから切り出して、それをbinary_to_listしてから処理した。
以下、シンプルバージョン(富豪バージョンとも言う)

#!/usr/bin/env escript

main(_) -> loop(io:get_chars('',1)).

loop(eof) -> show_histgram(lists:sort(get()));
loop(Chr) -> incr(Chr), loop(io:get_chars('',1)).

incr(Chr) ->
    case Count = get(Chr) of
    undefined -> put(Chr,1);
    _ -> put(Chr,Count + 1)
    end.

show_histgram([H|[]]) -> {K,V} = H, io:format("~p,~p~n",[K, V]);
show_histgram([H|L]) -> {K,V} = H, io:format("~p,~p~n",[K, V]), show_histgram(L).

このコードでもプロセス辞書(get, putしているもの、ハッシュだと思えばいい)を使っているが、writevのシステムコールが頻発しているのが気に入らない。
これはワークメモリ上で完結する処理にできないものか?

$ strace -c ./hist1.erl < 小さなテストデータ
"\t",160
"\n",1000
" ",3201
"!",7
"\"",130
"#",2
"%",802
"&",1
"'",254
"(",422
")",422
",",682
"-",3885
".",215
"/",166
"0",75
"1",75
"2",62
"3",25
"4",9
"5",4
"6",2
"7",2
"8",6
":",407
";",76
"<",10
"=",132
">",201
"?",63
"A",66
"B",10
"C",160
"D",136
"E",314
"F",147
"G",3
"H",135
"I",177
"K",12
"L",114
"M",82
"N",53
"O",346
"P",238
"R",121
"S",292
"T",235
"U",79
"V",146
"W",6
"X",7
"Y",4
"Z",1
"[",118
"]",118
"_",1388
"a",999
"b",126
"c",746
"d",433
"e",2990
"f",453
"g",336
"h",157
"i",1137
"j",15
"k",62
"l",939
"m",343
"n",971
"o",1526
"p",1020
"q",2
"r",1786
"s",1148
"t",1802
"u",341
"v",184
"w",114
"x",66
"y",449
"z",10
"{",81
"|",8
"}",81
 % time     seconds  usecs/call     calls    errors syscall
 ------ ----------- ----------- --------- --------- ----------------
 74.77    0.293033           8     35419           writev
  6.88    0.026954           9      2845           clock_gettime
  6.86    0.026880          10      2807           poll
  3.16    0.012374         128        97           read
  2.25    0.008801         677        13         8 execve
  1.53    0.005979          38       159        60 open
  0.99    0.003885          22       175        61 stat64
  0.73    0.002868          27       106           close
  0.39    0.001526         127        12           futex
  0.39    0.001510          94        16           munmap
  0.37    0.001459          58        25           getcwd
  0.37    0.001443          72        20           mprotect
  0.33    0.001299          38        34           fstat64
  0.25    0.000999          38        26           fcntl64
  0.16    0.000616         123         5         3 ioctl
  0.14    0.000551           6        93           mmap2
  0.14    0.000542           7        81           rt_sigaction
  0.13    0.000516         516         1           sigaltstack
  0.13    0.000503           5       101        53 access
  0.04    0.000151          38         4         2 waitpid
  0.00    0.000007           0        19           brk
  0.00    0.000003           1         5           set_thread_area
  0.00    0.000001           0        31           rt_sigprocmask
  0.00    0.000000           0         3           time
  0.00    0.000000           0         1           getpid
  0.00    0.000000           0         5           pipe
  0.00    0.000000           0         2           dup2
  0.00    0.000000           0         1           getppid
  0.00    0.000000           0         1           getpgrp
  0.00    0.000000           0        11           gettimeofday
  0.00    0.000000           0         1           readlink
  0.00    0.000000           0         2           sigreturn
  0.00    0.000000           0         2           clone
  0.00    0.000000           0         5           uname
  0.00    0.000000           0         4           _llseek
  0.00    0.000000           0         1           vfork
  0.00    0.000000           0         3           getrlimit
  0.00    0.000000           0         1           getuid32
  0.00    0.000000           0         1           getgid32
  0.00    0.000000           0         1           geteuid32
  0.00    0.000000           0         1           getegid32
  0.00    0.000000           0         8           getdents64
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           socket
  0.00    0.000000           0         1           bind
  0.00    0.000000           0         1           getsockname
  0.00    0.000000           0         3           setsockopt
  0.00    0.000000           0         2           getsockopt
 ------ ----------- ----------- --------- --------- ----------------
100.00    0.391900                 42158       187 total