トップ «前の日記(2003-06-28) 最新 次の日記(2003-06-30)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2003-06-29

_ 速度、可読性、保守性

 以下のうーんざりするようなコード片を目にした場合、どう対処できるか? (テーブルには手が出せないものとする)
stmt.setInt(1, a.getA1());
stmt.setInt(2, a.getA2());
...
stmt.setInt(120, a.getA120());
stmt.executeUpdate();
良く、aで示されるクラスを作ったもんだと思わなくも無いが、それにしてもこんなの120行も書いていて、何か変だと思わないのか? と訊けば、良くぞ訊いてくださったとばかりに、最近のエディタはちゃんとしたマクロがありますから問題ありません、と平然と答えたりして。ほーそうか。それにしても良く120個もゲッタを持ったビーンを作ったものだなぁ。と言うと、最近の統合環境では……あぁ、君は黙っていてくれたまえ。 120個もゲッタがある、しかも120個もインスタンス変数があるのなら、例えば、こういう手法は考えつかんのか?
class A {
  private Map map;
  public int get(String key) { return ((Integer)map.get(key)).intValue(); }
  ...
}
....
String[] keys = { "A1", "A2" ... };
...
for (int i = 0; i < keys.length; i++) {
  stmt.setInt(i + 1, a.get(keys[i]));
}
...
で、これにどういう意味があるんですか? Integerのインスタンスをかます分だけ効率も悪いし、GCの頻度が増すのでストレステストになるということですか? −それは一理あるが、今、問題にしているのは、この1000行もあるアホウなメソッドをどうにかしろ、ということなんだ。でも、まあ、mapを使うのはこの場合、意味なさすぎだな。それじゃ
class A {
  private int[] vals;
  public int get(int idx) { return vals[idx]; }
  public int size() { return vals.length; }
}
...
for (int i = 0, n = a.size(); i < n; i++) {
  stmt.setInt(i + 1, a.get(i));
}
ならどうだ? −でも、これだと、たとえばインデックス32がAのどのような属性かさーぱりわからないんですが。やっぱり、ちゃんとゲッタを定義したほうがいいと思います。−面倒なヤツだな。じゃあ、これならどうだ?
class A {
  private int[] vals;
  public int get(int index) { return vals[index]; }
  public int size() { return vals.length; }
  ...
  public int getA32() { return vals[32]; }
  ...
}
あのぁ、ここにvals[32]というマジックナンバーがあるんですけど。マジックナンバーは書いてはいけないということも知らないんですか? 私なら
class A {
  private int[] vals;
  ...
  static final int A1 = 0;
  ...
  static final int A32 = 31;
  ...
  public int getA32() { return vals[A32]; }
  ...
}
としますが、何か? −なるほどねぇ。そういうふうにプログラムを記述してれば、そりゃ、テストプログラムを作ったり、リファクタリングする暇は無いだろうねぇ。
#でも、結局、更新対象カラム数が多ければ多いほど致命的に遅くなることが判明して、
StringBuffer s = new StringBuffer("update ... set ");
for (int i = 0; i < a.size(); i++) {
  if (a.get(i) != 0) {
    s.append("A").append(i + 1).append("=A").append(i + 1).append("+?,");
  }
}
...
int col = 1;
for (int i = 0; i < a.size(); i++) {
  if (a.get(i) != 0) {
    stmt.setInt(col++, a.get(i));
  }
}
...
となったりして。
本日のツッコミ(全2件) [ツッコミを入れる]
_ ただただし (2003-06-29 09:08)

うちは、しゅーしゅー先生1号相当のが現役です。可動部分がないから壊れない……

_ arton (2003-06-29 09:33)

僕も1号は好き(なかなかフォトジェニックだし)なんですけどね。2号も可動部分は無いんですが、ちょっと使い方が荒くて錆が出たりしてたのが原因かな。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|

ジェズイットを見習え