StringBuffer の速さ、String.replace の遅さ

一つの String に対していろいろな置換を行った結果を得たいとき、
String.replace を繰り返し適用すると、無駄な時間がかかる。
これは、

  • String オブジェクトが置換の回数だけ生成される
  • String.replace が正規表現置換 (String.replaceAll 相当) を内部で使っている (おそらくこの点は、JDKの実装に依存する)

ことに起因する。

import java.util.Map;
import java.util.HashMap;

public class T {
    static Map<String,String> mapping;
    static {
        mapping = new HashMap<String,String>();
        mapping.put("1", "one");
        mapping.put("2", "two");
        mapping.put("3", "three");
        mapping.put("4", "four");
    }
    static String exec1(String arg){
        String result = arg;
        for (Map.Entry<String, String> m : mapping.entrySet()) {
            int i;
            while ( ( i = result.indexOf(m.getKey())) >= 0 ) {
                result = result.substring(0, i) + m.getValue() + result.substring(i+m.getKey().length());
            }
            //result = result.replace(m.getKey(), m.getValue());
        }
        return result;
    }
    static String exec2(CharSequence arg){
        StringBuffer result = new StringBuffer(arg);
        for (Map.Entry<String, String> m : mapping.entrySet()) {
            int i;
            while ( ( i = result.indexOf(m.getKey())) >= 0 ) {
                result.replace(i, i+m.getKey().length(), m.getValue());
            }
        }
        return result.toString();
    }
    public static void main(String[] args) throws InterruptedException {
        String s = "";
        for ( int i = 0; i < 500000; i++ ) {
            s = exec2("123412341234123412341234123412341234");
        }
        Thread.sleep(s.length()/100);
    }
}

wordnet フォーマット

data.* は 1行が 1 synset に対応する同義語辞書ファイル。
たとえばこの行

08499057 15 n 02 atmosphere 0 air 1 007 @ 08630039 n 0000 #p 09270894 n 0000 + 02831736 a 0101 + 02831736 a 0102 ~ 08502317 n 0000 %p 08555569 n 0000 %p 08588916 n 0000 | the mass of air surrounding the Earth; "there was great heat as the comet entered the atmosphere"; "it was exposed to the air"

の先頭部分は、カラムごとに次の意味。

08499057

このファイルでのこの synset 行のバイトオフセット。このオフセットは、synset に対する ID としても使われる。

15

このsynsetを含んでいるlexicographer file のID。たぶん普通は使わない。

n

POS。次の五種類:

n NOUN
v VERB
a ADJECTIVE
s ADJECTIVE SATELLITE
r ADVERB

02

synset に入っている単語の数。

atmosphere 0
air 1

このsynset が "atomosphere" の語義0と "air" の語義1からなることを示す。この部分が同義語辞書としてもっとも重要な情報。

007

以降に記述される、この synset から 別の synset への関係の数。
関係としては、上位語、全体語などがある。
関係は、"@"(上位) "~" (下位)などのシンボルとsynset offset の組で記述される。
↓シンボルのドキュメント
http://wordnet.princeton.edu/man/wninput.5WN.html#sect3

↓ data.(noun|adj)ファイルの書式についてのドキュメント
http://wordnet.princeton.edu/man/wndb.5WN#sect3

git の個人的慣習としてつくるレポジトリとブランチの初期設定

フォークの場合、元のレポジトリを ssh:/gw/~uuu/git-repos/xxx に clone しておく。
新規の場合、同じ場所に単に空のレポジトリを作る。

・レポジトリ
origin: 非公開の中央レポジトリ、基本的に一人用

git clone ssh://gw/~uuu/git-repos/xxx

public: (公開する場合)公開する場所、githubなど、共有されているかもしれない

git remote add public git@github.com:xxx/xxx.git
git pull public

・ブランチ
master: 切りのいいバージョンを残す用、他のレポジトリからのフォークの場合は、本体の更新は基本的にこちらでpullする
dev: 通常作業用、ふだんはこちらを checkout しておく

git branch dev

さらに実験的な追加の場合は、別のブランチを作ってその上で作業&コミットし、
フィックスされてきたら dev → master → origin, public と反映させる。

・通常作業
dev ブランチで作業

git co dev

ローカルレポジトリにコミット

git commit

開発版だけど保存はしておきたい → 中央レポジトリにpush

git push origin dev

一段落したのを保存 → 上流公開レポジトリとの開発版とのマージをmasterブランチでとる

git co master
git merge dev
git pull public

git-svn でレポジトリ変換

git clone svn+ssh://.... newdir

で変換。
svn では複数のプロジェクトが一つのレポジトリにあったりするので、
ルートディレクトリ直下のディレクトリをひとつのgitレポジトリとするのがいい。

初期状態だとgcかかってないので、かけること。

更新は git-svn rebase

git undo

コミットログの編集

git commit --amend

local repository を前回のコミット前の状態に戻す

git reset --soft HEAD^

ワークスペース、index, local repository を前回のコミット時の状態に戻す
(更新された実体ファイルも戻す)

git reset --hard