[ruby-dev:25997] Re: some trouble on ext/tk/sample
From:
Hidetoshi NAGAI <nagai@...>
Date:
2005-04-06 16:21:19 UTC
List:
ruby-dev #25997
永井@知能.九工大です.
From: H.Yamamoto <ocean@m2.ccsnet.ne.jp>
Subject: [ruby-dev:25996] Re: some trouble on ext/tk/sample
Date: Wed, 6 Apr 2005 23:02:43 +0900
Message-ID: <20050406230220.545777F0.ocean@m2.ccsnet.ne.jp>
> >判断誤りの心配がなくそれだけ早くなるなら有効な対策かもしれませんね.
> すみません、このパッチは試しに作ったいい加減なパッチで、
> 例えば ascii 互換でないエンコーディングが存在して、
> tcl がそれをサポートしていて、そういった文字が渡ってきた場合は
> 考慮していませんでした。それ以外でもちゃんと動くか怪しいです。
例えば ebcdic とか.(^_^)
> うわー、手動でやらないといけないんですね・・・何とか自動化できないか
> しばらく考えたんですが、「ascii 非互換なエンコーディングは ID_at_enc を
> 指定した文字列という形でしか使えない」という感じにしないと無理そうで・・・
> 無理なのかなあ。
自動ってのは難しいでしょうねぇ...
半端な制約を付けるくらいなら,いっそのこと「非 ascii は utf-8 に
変換してから渡すこと」としてしまった方が潔いでしょう.
ちなみに tk_call_without_enc などを使うというスピード対策は,
本来ライブラリで行っておくべきことです.
そうするためには,引数として与えられるものにはどういうクラスや
表現がありうるか,戻り値はコード変換の必要がありうるか等を注意
して判断する必要があるのですが,最初のインプリメントではそれを
サボって安易な実装をしてしまっています.(^_^;
# まずはとにかく使えるようにしておいて,それから要望に合わせて
# スピードアップというわけです.
Ruby/Tk でのスピードアップ手順としては,
(1) 安易な tk_call での引数を調べ,コード変換の必要が
ないものは変換させないようにする.
tk_call --> tk_call_without_enc + _get_eval_string
(2) 引数のクラスが明確であるならば,_get_eval_string
に頼らない.
(3) 情報を保存しておく等して Ruby 側で処理できる部分
を増やし,Tk 側を呼び出す回数を減らす.
(4) どうしても頻繁に呼ばねばならない部分であれば,
あきらめて TkCore::INTERP._invoke_without_enc を
直接使う.
(5) 繰り返し Tk 側を呼び出す必要がある部分で,ある程度
まとまった手続きとみなせる部分なら,いっそのこと
Tk.ip_eval などを使って Tk 側に Tcl のプロシージャを
作ってしまい,それを呼び出すようにする.
というようなことになるだろうと思います.
# (4) や (5) は Ruby を使っているという感じでは
# なくなってくるのが難点ですが.(^_^)
# (4) くらいまでやると,速度が1桁以上違ってくるかもしれません.
ライブラリが tk_call を安易に使っていても,
そこがスピードに大きく影響している部分であれば,
ライブラリの定義を参照に override すればいいですよね.
汎用となるライブラリでは制約できなくても,
自分のスクリプトの中では引数のクラスを確定させて
考えることができるでしょうから,難しくはない対策のはずです.
例えば,tktreectrl.rb で (1) の対策を行うなら
以下のような感じかと思います.
ただしこの例は (1) の中でも安易なもので,
確定文字列以外はチェックするというという程度のものです.
もっと詳細な調査をやれば,変換をパスできる部分が
あるだろうと思います.
ちなみに,ざっと急いで変更したものなので,
問題がないかどうかや効果の程度は調べていません.
多分,効果はあると思うのですが...
もしテストしてみて問題がなく,効果も大きいようなら
commit していただいてもかまいません.
あるいは,言っていただければ暇を見つけて commit します.
--- tktreectrl.rb.old 2005-04-02 15:37:13.000000000 +0900
+++ tktreectrl.rb 2005-04-07 01:08:45.000000000 +0900
@@ -554,12 +554,13 @@
end
def collapse(*dsc)
- tk_send('collapse', *dsc)
+ tk_send_without_enc('collapse', *(dsc.map!{|d| _get_eval_string(d, true)}))
self
end
def collapse_recurse(*dsc)
- tk_send('collapse', '-recurse', *dsc)
+ tk_send_without_enc('collapse', '-recurse',
+ *(dsc.map!{|d| _get_eval_string(d, true)}))
self
end
@@ -610,7 +611,7 @@
end
def depth(item=None)
- num_or_str(tk_send('depth', item))
+ num_or_str(tk_send_without_enc('depth', _get_eval_string(item, true)))
end
def dragimage_add(item, *args)
@@ -750,22 +751,25 @@
end
def item_collapse(item)
- tk_send('item', 'collapse', item)
+ tk_send_without_enc('item', 'collapse', _get_eval_string(item, true))
self
end
def item_collapse_recurse(item)
- tk_send('item', 'collapse', item, '-recurse')
+ tk_send_without_enc('item', 'collapse',
+ _get_eval_string(item, true), '-recurse')
self
end
def item_complex(item, *args)
- tk_send('item', 'complex', item, *args)
+ tk_send_without_enc('item', 'complex',
+ _get_eval_string(item, true),
+ *(args.map!{|arg| _get_eval_string(arg, true)}))
self
end
def item_create(keys={})
- num_or_str(tk_send('item', 'create', keys))
+ num_or_str(tk_send_without_enc('item', 'create', *hash_kv(keys, true)))
end
def _erase_children(item)
@@ -814,10 +818,13 @@
def item_firstchild(parent, child=nil)
if child
- tk_send('item', 'firstchild', parent, child)
+ tk_send_without_enc('item', 'firstchild',
+ _get_eval_string(parent, true),
+ _get_eval_string(child, true))
self
else
- id = num_or_str(tk_send('item', 'firstchild', parent))
+ id = num_or_str(tk_send_without_enc('item', 'firstchild',
+ _get_eval_string(parent, true)))
Tk::TreeCtrl::Item.id2obj(self, id)
end
end
@@ -825,9 +832,12 @@
def item_hasbutton(item, st=None)
if st == None
- bool(tk_send('item', 'hasbutton'))
+ bool(tk_send_without_enc('item', 'hasbutton',
+ _get_eval_string(item, true)))
else
- tk_send('item', 'hasbutton', st)
+ tk_send_without_enc('item', 'hasbutton',
+ _get_eval_string(item, true),
+ _get_eval_string(st))
self
end
end
@@ -860,10 +870,13 @@
def item_lastchild(parent, child=nil)
if child
- tk_send('item', 'lastchild', parent, child)
+ tk_send_without_enc('item', 'lastchild',
+ _get_eval_string(parent, true),
+ _get_eval_string(child, true))
self
else
- id = num_or_str(tk_send('item', 'lastchild', parent))
+ id = num_or_str(tk_send_without_enc('item', 'lastchild',
+ _get_eval_string(parent, true)))
Tk::TreeCtrl::Item.id2obj(self, id)
end
end
@@ -881,7 +894,8 @@
alias item_next_sibling item_nextsibling
def item_numchildren(item)
- number(tk_send('item', 'numchildren', item))
+ number(tk_send_without_enc('item', 'numchildren',
+ _get_eval_string(item, true)))
end
alias item_num_children item_numchildren
alias item_children_size item_numchildren
@@ -1005,15 +1019,23 @@
def item_style_set(item, column=nil, *args)
if args.empty?
if column
- id = tk_send('item', 'style', 'set', item, column)
+ id = tk_send_without_enc('item', 'style', 'set',
+ _get_eval_string(item, true),
+ _get_eval_string(column, true))
Tk::TreeCtrl::Style.id2obj(self, id)
else
- list(tk_send('item', 'style', 'set', item)).collect!{|id|
+ list(tk_send_without_enc('item', 'style', 'set',
+ _get_eval_string(item, true))).collect!{|id|
Tk::TreeCtrl::Style.id2obj(self, id)
}
end
else
- tk_send('item', 'style', 'set', item, column, *(args.flatten))
+ tk_send_without_enc('item', 'style', 'set',
+ _get_eval_string(item, true),
+ _get_eval_string(column, true),
+ *(args.flatten.map!{|arg|
+ _get_eval_string(arg, true)
+ }))
self
end
end
--
永井 秀利 (九工大 知能情報)
nagai@ai.kyutech.ac.jp