STRINGクラスのメリット

返信する


答えを正確に入力してください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: STRINGクラスのメリット

by OverTaker » 2007年1月04日(木) 12:09

tak さんが書きました:バッファ用途としての応用性が現状では狭い
この件に関してですが、実は結構前に大丈夫なんじゃないかなーと、考えていました。というのも、ライブラリが完成してしまえば、そもそも直にAPIで操作することがなくなるのではないかと考えているからです。
ただ、現状を見てまだライブラリが完成していませんし、APIを使おうとすると、やはりこの問題が出てくるので、何か対処できるのであれば、対処したいですね。

by konisi » 2007年1月04日(木) 02:51

最初の方だけしか逆アセンブルの結果を見てなかったのでimulの存在を消去してしまっていたのですが、よく調べると二つの即値Pushが配列の番号を示しているようで、そこからアドレスを計算するために整数積算が使われている事が判明しました。

by tak » 2007年1月04日(木) 02:39

順番が逆になってしまったのですが、こちらが本題です。
String クラスのメリットについてはいくつか挙がっておりますが、デメリットについて(サイズ以外に)触れられていないので、僕の思いつく分だけこちらで。 こんなところでしょうか。全部展開するとそれなりの長文になりますので、ご注意ください :-p

by konisi » 2007年1月04日(木) 02:20

ABで言うと、今現在code1のようになってるからcode2のようにした方がファイルサイズレベルで効率的ではないのか? という話です。

code1

コード: 全て選択

Dim A(100) As Long
A(0)=0
A(1)=0
A(2)=0
'   ・・・(省略
A(100)=0
code2

コード: 全て選択

Dim A(100) As Long,i As Long
For i=0 To 100
    A(i)=0
Next i
理解してもらえれば嬉しい。
又、すぐにでも書き直せるかと言われれば、newでの初期化がファイルサイズから見ておそらくcode2のようになっているので、それをコピーして少し改変する程度だと思っていますが・・・。

by OverTaker » 2007年1月04日(木) 01:47

静的確保・動的確保云々以前の問題として、クラスの配列の総当り的初期化で多くの機械語が生成されていると判断します。
ループするように書き直したほうが良いのでは?
私はよくわからないのですが、修正した方がいいのだと思います。しかし、このレベルの最適化は後からでもいいと思うのですが、どうなんでしょうか?山本さん一人だけでは限界がありますから、今優先すべきタスクから消化していくべきだと思います。

私の感覚だと、最適化のタスクの優先順位はかなり低い方です。ただ、これは人それぞれで変わりますし、バランスも重要です。結局最終的にタスクをこなされるのは山本さんなので、私の主観はあまり関係ないですけどね。あと、この修正に時間を要さないのであれば、こんなこと話すのも無駄でしょうが。
静的確保・動的確保云々以前の問題として
とありますが、先ほどの投稿はこの意も含めての投稿だったというわけです。最初に言ったように、言語より下のことはわかりませんので、後はkonisiさんに任せます。

by konisi » 2007年1月04日(木) 01:13

実際に見てもらえば分かると思うのですが、String型を静的に10万個確保したファイルのうち、約82%が上に挙げたような機械語でした。

静的確保・動的確保云々以前の問題として、クラスの配列の総当り的初期化で多くの機械語が生成されていると判断します。
ループで初期化するように書き直したほうが良いのでは?

by イグトランス » 2007年1月04日(木) 00:07

SizeOf (String) × 要素数 = 8 × 100000 = 8000000となることから,静的に確保した場合に8MBほどになるのはこの分を変数の初期化内容として丸ごと実行ファイル内に抱え込んでいると考えれば納得がいきます。

このString型配列変数の領域にBSSセクション(実行開始時に0初期化されるメモリ領域で,実行ファイル内に初期化内容は含まれない)を活用してもらえれば,ファイルの大きさは縮むことが予想できます。

by konisi » 2007年1月03日(水) 23:15

動的に確保すると言う事をあまりやらないkonisiです。
なるほど、そう書けばサイズが小さくなるんですか。ありがとうございます。

by OverTaker » 2007年1月03日(水) 23:01

コード: 全て選択

Dim A(100000) As String
というコードだけでファイルサイズが8.42MBって言うのは少し大きすぎやしないでしょうか^^;
私は、言語より下の知識がほとんどないに等しいので、あまり偉そうなことは言えないのですが、このサンプルはちょっと特異し過ぎてるのではないでしょうか?一般的に、このようなコードを書くことは少ないと思います。たぶん、大容量データを扱いたい場合、静的ではなく、動的に確保するのが一般的かと思われます。

コード: 全て選択

Dim s As *String
s = New[100000] String
このコードは、最新のβ版では、36.0KBになります。

by konisi » 2007年1月03日(水) 22:46

コード: 全て選択

Dim A(100000) As String
というコードだけでファイルサイズが8.42MBって言うのは少し大きすぎやしないでしょうか^^;
コンパイルの速度も少し落ちたような気がします。
調べてみると、AB5系では次のようなコードが生成されています。

コード: 全て選択

    XOR     ECX,ECX
    PUSH    ECX
    PUSH    00h
    PUSH    00h
    POP     EAX
    IMUL    EAX,EAX,00000001h
    ADD     dword ptr[ESP],EAX
    POP     EAX
    IMUL    EAX,EAX,00000008h
    POP     ECX
    ADD     ECX,EAX
    LEA     EAX,[ECX+C6C724h]
    MOV     ECX,EAX
    PUSH    ECX
    CALL    _A
これが延々と。

せめてこう書き直したほうが良いのではないかという案。

コード: 全て選択

    PUSH    0C6C724h
    CALL    _A
と言うより、省略できるところをどんどん省略して行ったらこんなに小さくなっちゃったんですが、
自動化のほう、どうなっているんでしょうか山本さん。

追記:実行箇所がどこに飛ばされているかと言う点と、それの最適化案について。

コード: 全て選択

;生成されるコード
_A:
    SUB     ESP,00000000h
    PUSH    EBP
    MOV     EBP,ESP
    PUSH    EBX
    PUSH    ESI
    PUSH    EDI
    PUSH    01h
    CALL    _B
    PUSH    EAX
    MOV     ECX,dword ptr[EBP+08h]
    ADD     ECX,00000004h
    POP     EAX
    MOV     dword ptr[ECX],EAX
    PUSH    00h
    MOV     ECX,dword ptr[EBP+08h]
    POP     EAX
    MOV     dword ptr[ECX],EAX
    POP     EDI
    POP     ESI
    POP     EBX
    MOV     ESP,EBP
    POP     EBP
    ADD     ESP,+00h
    RET     0004h

_B:
    SUB     ESP,00000004h
    PUSH    EBP
    MOV     EBP,ESP
    PUSH    EBX
    PUSH    ESI
    PUSH    EDI
    PUSH    00h
    PUSH    04h
    MOV     EAX,EBP
    ADD     EAX,00000004h
    PUSH    EAX
    CALL    dword ptr[KERNEL32.RtlFillMemory]
    PUSH    dword ptr[EBP+0Ch]
    PUSH    08h
    PUSH    dword ptr[offset D]
    CALL    dword ptr[KERNEL32.HeapAlloc]
    PUSH    EAX
    POP     EAX
    MOV     dword ptr[EBP+04h],EAX
    JMP     _C

_C:
    MOV     EAX,dword ptr[EBP+04h]
    POP     EDI
    POP     ESI
    POP     EBX
    MOV     ESP,EBP
    POP     EBP
    ADD     ESP,+04h
    RET     0004h

コード: 全て選択

;最適化してみたコード
_A:
    SUB     ESP,00000000h
    PUSH    EBP
    MOV     EBP,ESP
    PUSH    EBX
    PUSH    ESI
    PUSH    EDI;ここまでは関数の定石なのでここは削らない。ただし残す必要性は薄い。以下略。
    ;EAX,ECXは_B先でも現在の値が参照されないので初期化はしない。
    PUSH    01h
    CALL    _B
    MOV     ECX,dword ptr[EBP+08h]
    MOV     dword ptr[ECX+04h],EAX
    XOR     EAX,EAX
    MOV     ECX,dword ptr[EBP+08h]
    MOV     dword ptr[ECX],EAX
    POP     EDI;ここから関数の定石なので削らない。
    POP     ESI
    POP     EBX
    MOV     ESP,EBP
    POP     EBP
    ADD     ESP,+00h
    RET     0004h

_B:
    SUB     ESP,00000004h
    PUSH    EBP
    MOV     EBP,ESP
    PUSH    EBX
    PUSH    ESI
    PUSH    EDI;ここまで関数の定石なので削らない。
    PUSH    00h
    PUSH    04h
    MOV     EAX,EBP
    ADD     EAX,00000004h
    PUSH    EAX
    CALL    dword ptr[KERNEL32.RtlFillMemory]
    PUSH    dword ptr[EBP+0Ch]
    PUSH    08h
    PUSH    dword ptr[offset D]
    CALL    dword ptr[KERNEL32.HeapAlloc]
    MOV     dword ptr[EBP+04h],EAX
    POP     EDI;ここから関数の定石なので削らない。
    POP     ESI
    POP     EBX
    MOV     ESP,EBP
    POP     EBP
    ADD     ESP,+04h
    RET     0004h

by OverTaker » 2007年1月03日(水) 20:46

やはり、文字列操作が簡単になる等、開発の負担が減るということが一番のメリットだと思います。
あとは、他のライブラリも整ってきたときに、Stringクラスの価値が再確認できると思います。具体的には、Array(配列)クラスなどを使って、Stringクラスの配列を容易に扱えるようになったりすることです。
ちなみに気づいたのですが、デメリットとして、
STRINGクラスのデータを定義すると個数によってEXEのサイズが大きくなるようです。
気にされる方はそうかもしれませんが、私は全然気にしていません。今後、ActiveBasicのexeサイズは増加することが予想されますので、気にする方はちょっと残念ですね。しかし、今よりも格段に開発が楽になると思います。

by イグトランス » 2007年1月03日(水) 16:21

配列変数定義の上限値について
String型がまだクラスで無かった頃,Stringの配列型の変数を宣言すると,さして大きくない要素数でもコンパイラがエラーになってしまうという現象がありました。
クラスならNewが使えるのでこの問題は回避できるだろうと当時の私は主張していますね。
#汎用性という観点からすればクラス型でなくてもNew/Deleteが使えるほうが良いと私は思いますけどね。

Re: STRINGクラスのメリット

by 7 » 2007年1月03日(水) 14:17

> 普段、なにげなく使用するSTRINGクラス。
やっと最近なにげなく使用するようになりました。

> そこで質問です。
> STRINGクラスのメリットってどんなものケースがありますか?
自分が感じた限りでは、開発する際の負担が軽減されたことでしょうか?
Insert関数やRemove関数などと同じ機能をもった関数を自分で用意して開発してたのが、「公式」という一応の安全を確保された物として提供してくださるので、なんとな~く安心して使えます。

> ちなみに気づいたのですが、デメリットとして、
> STRINGクラスのデータを定義すると個数によってEXEのサイズが大きくなるようです。
こういったことの逆でメリットを挙げるとするならとくに気付かないんですけど...。

とりあえず、文字列操作に関する細かい作業を気にすることなくStringクラスを使うだけで作業が済んでしまうという効率の良さがメリットでしょうか?。

STRINGクラスのメリット

by たかせ » 2007年1月03日(水) 13:55

たかせです。

普段、なにげなく使用するSTRINGクラス。
CP2から導入されましたが。
一部分を除き4.24以前のバージョンと同様になにも気にせずに使用できます。

当然、内部動作に差異はありますが。

そこで質問です。
STRINGクラスのメリットってどんなものケースがありますか?

よろしくおねがいします。

ちなみに気づいたのですが、デメリットとして、
STRINGクラスのデータを定義すると個数によってEXEのサイズが大きくなるようです。

ページトップ