線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:7464
推到 Plurk!
推到 Facebook!

翻译:FieldByName, FindField确实太好用了

 
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2012-11-02 22:22:16 IP:111.249.xxx.xxx 未訂閱
來源出處: http://www.delphifans.com/infoview/Article_6519.html

有點感慨這麼有意思的文章只有幾個人能夠分享了…

文章內所介招的技巧其實BCB玩久的人應該會不經意的使用到

因為BCB沒有「with DataSet do」!

哈哈!
編輯記錄
GrandRURU 重新編輯於 2012-11-02 08:24:23, 註解 無‧
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2012-11-03 00:38:38 IP:118.160.xxx.xxx 未訂閱
早期我設計都是先把 Field 拉到  FieldEditor 中,先建立好所有Field Define 的內容, 使用上很方便只要引用  Query1MYFIELD1.Value 即可, 但最大的問題是, 如果改變了資料庫結構的 Lengths, 就得到每一個DataModule中相關的 Fields 去修正長度, 否則整套程式就會很好"完"了, 
後來看好多書都是使用 FieldByName(xxx), 所以也大量使用, 確實不要先Define各欄位的定義, 省了好多事, 也靈活多了, 但我一直不解的是為什麼現在開發的讀取速度比以前慢很多, 今天看了這篇之後, 真相大白! 原來如此!
真的, 一堆書害死人, 都完全沒提這檔事, 我都用了好多年了, 回頭要改程式也不是那麼容易, 上萬個FieldByName 想到就頭大,
感謝RuRu兄的提供, 改天按上面所說的改一個來測測看, 是否效能真的夠加快!
老大仔
尊榮會員


發表:78
回覆:837
積分:1088
註冊:2006-07-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2012-11-03 09:48:58 IP:114.26.xxx.xxx 未訂閱
 前幾天在做一個匯出Excel的功能
資料量也算還好 就幾千筆而已
但是速度很慢
後來光是加了DisableControls、EnableControls
整個速度提升非常多
我在猜~
是否是因為減少了”顯示”(反應)在物件的動作上
所以速度可以更快?

leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2012-11-03 10:52:10 IP:115.81.xxx.xxx 訂閱
7個方法 要改之前可以先看看
http://delphi.about.com/od/database/ss/faster-fieldbyname-delphi-database_7.htm
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2012-11-03 18:45:02 IP:182.235.xxx.xxx 未訂閱
謝謝leveon大大的分享!

我分享的連結也在您說的這篇主題裡面耶
追加連結:How Fast Can You "FieldByName"?

想不到原先的方法在第三頁就被開槍了
哈哈

研究中,再次謝謝您的分享!

===================引 用 leveon 文 章===================
7個方法 要改之前可以先看看
http://delphi.about.com/od/database/ss/faster-fieldbyname-delphi-database_7.htm
編輯記錄
GrandRURU 重新編輯於 2012-11-03 04:48:41, 註解 無‧
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2012-11-03 20:15:10 IP:182.235.xxx.xxx 未訂閱
他的HookTDataset / UnHookTDataset這段看的不是很明瞭

不知道這應該怎麼解讀呢?

底下是節錄原文:
I simply managed to hook the TDataset.FindField at runtime and replaced the procedure with my own.
The advantage of this solution if of cause you get the speed instantly. If you enable the compiler directive, then Tdataset are hooked on startup, else you'll have to do it you self by calling HookTDataset. If you by some reason wants to restore the original code then this can be done by calling UnHookTDataset.
All the other stuff with GetFieldList etc are of cause still there. So until you get the time/need for refactoring you could use this unit to speed up FieldByname
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2012-11-03 20:54:07 IP:114.42.xxx.xxx 訂閱
如你有定義 HookDataset_ON_Initialization 這個macro,那麼你就無需要再去執行HookTDataset這個程序,它會在單元載入時就被載入,你去看FieldByNameSpeedUp.pas大的最下面:

initialization
{$IFDEF HookDataset_ON_Initialization}
HookTDataset;
{$ENDIF}

當然,若你想要隨時的調幅原汁原的那個TField,你可以調UnHookTDataset來復原。若程式到了需要再用快速的那個時,就再次調用HookTDataset。但原則上若你覺得這個hook很好用,原則上你應該不會再調用原汁原味的那個,所以作者才會設計一個macro,讓你"自然的"就使用。





===================引 用 GrandRURU 文 章===================
他的HookTDataset / UnHookTDataset這段看的不是很明瞭

不知道這應該怎麼解讀呢?

底下是節錄原文:
I simply managed to hook the TDataset.FindField at runtime and replaced the procedure with my own.
The advantage of this solution if of cause you get the speed instantly. If TFieldyou enable the compiler directive, then Tdataset are hooked on startup, else you'll have to do it you self by calling HookTDataset. If you by some reason wants to restore the original code then this can be done by calling UnHookTDataset.
All the other stuff with GetFieldList etc are of cause still there. So until you get the time/need for refactoring you could use this unit to speed up FieldByname
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2012-11-03 06:55:51, 註解 無‧
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2012-11-03 21:37:45 IP:182.235.xxx.xxx 未訂閱
意思是只要有這個HookTDataset

這樣就不需要GetFieldList(ClientDataSet1)嗎?

如果能夠直上
DataSet.FieldByName就更好了

===================引 用 aftcast 文 章===================
如你有定義 HookDataset_ON_Initialization 這個macro,那麼你就無需要再去執行HookTDataset這個程序,它會在單元載入時就被載入,你去看FieldByNameSpeedUp.pas大的最下面:

initialization
{$IFDEF HookDataset_ON_Initialization}
HookTDataset;
{$ENDIF}

當然,若你想要隨時的調幅原汁原的那個TField,你可以調UnHookTDataset來復原。若程式到了需要再用快速的那個時,就再次調用HookTDataset。但原則上若你覺得這個hook很好用,原則上你應該不會再調用原汁原味的那個,所以作者才會設計一個macro,讓你"自然的"就使用。





===================引 用 GrandRURU 文 章===================
他的HookTDataset / UnHookTDataset這段看的不是很明瞭

不知道這應該怎麼解讀呢?

底下是節錄原文:
I simply managed to hook the TDataset.FindField at runtime and replaced the procedure with my own.
The advantage of this solution if of cause you get the speed instantly. If TFieldyou enable the compiler directive, then Tdataset are hooked on startup, else you'll have to do it you self by calling HookTDataset. If you by some reason wants to restore the original code then this can be done by calling UnHookTDataset.
All the other stuff with GetFieldList etc are of cause still there. So until you get the time/need for refactoring you could use this unit to speed up FieldByname
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#9 引用回覆 回覆 發表時間:2012-11-03 22:37:17 IP:114.42.xxx.xxx 訂閱
完全幾乎無痛的方式看來似乎不太可能,我花幾分鐘看了一下架構,那作者不是針對 dataset.FieldByName來hook,我想這是有原因的。它加速的原理不是去改原來的那個FieldByName的演算法,因為可能也沒什麼可加速的,所以才去hook

HookProc(@TFastDataset.DoAfterOpen , @TFastDataset.NewDoAfterOpen , TDatasetDoAfterOpen);
HookProc(@TFastDataset.DoAfterClose , @TFastDataset.NewDoAfterClose, TDatasetDoAfterClose);
HookProc(@TDataset.FindField , @TFastDataset.NewFindField , TDatasetFindField);

這三個方法來「間接」達成任務。實作我完全沒看啦…但架構上看來的感覺是那樣。

「所以DataSet.FieldByName就更好了」,看來是不可行的。
平常還是要養成"良好"的習慣比較重要,我個人在loop中,經常是不用方法來重複的找某個屬性然後改值。我都是設變數(一次工),然後再進loop裡,不只是這個DataSet.FieldByNam,所有這類取物件再設值的事,我都是先在loop外取物件(一次),然後進loop。

過去就給它過去了吧…要看未來比較重要…哈哈
===================引 用 GrandRURU 文 章===================
意思是只要有這個HookTDataset

這樣就不需要GetFieldList(ClientDataSet1)嗎?

如果能夠直上
DataSet.FieldByName就更好了

===================引 用 aftcast 文 章===================
如你有定義 HookDataset_ON_Initialization 這個macro,那麼你就無需要再去執行HookTDataset這個程序,它會在單元載入時就被載入,你去看FieldByNameSpeedUp.pas大的最下面:

initialization
{$IFDEF HookDataset_ON_Initialization}
HookTDataset;
{$ENDIF}

當然,若你想要隨時的調幅原汁原的那個TField,你可以調UnHookTDataset來復原。若程式到了需要再用快速的那個時,就再次調用HookTDataset。但原則上若你覺得這個hook很好用,原則上你應該不會再調用原汁原味的那個,所以作者才會設計一個macro,讓你"自然的"就使用。





===================引 用 GrandRURU 文 章===================
他的HookTDataset / UnHookTDataset這段看的不是很明瞭

不知道這應該怎麼解讀呢?

底下是節錄原文:
I simply managed to hook the TDataset.FindField at runtime and replaced the procedure with my own.
The advantage of this solution if of cause you get the speed instantly. If TFieldyou enable the compiler directive, then Tdataset are hooked on startup, else you'll have to do it you self by calling HookTDataset. If you by some reason wants to restore the original code then this can be done by calling UnHookTDataset.
All the other stuff with GetFieldList etc are of cause still there. So until you get the time/need for refactoring you could use this unit to speed up FieldByname
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2012-11-04 00:16:47 IP:111.240.xxx.xxx 訂閱
沒測試 不過感覺是無痛
Hook的原因 應該是不想直接改VCL的Source
沒去動Fieldbyname的原因是 Fieldbyname 本身就是去調用 FindField
只要推升FindField的效率 就可以間接改進Fieldbyname

function TDataSet.FieldByName(const FieldName: string): TField;
begin
Result := FindField(FieldName);
if Result = nil then DatabaseErrorFmt(SFieldNotFound, [FieldName], Self);
end;
他的利基似乎 是利用 TStringList.Sorted := true 後 IndexOf 就會變快

順手又翻了一些資料
http://www.gefvert.org/blog/archives/651
http://www.delphigeist.com/2010/02/super-fast-string-list-replacement.html
要再鑽下去可能是沒完沒了 顆顆


===================引 用 aftcast 文 章===================
完全幾乎無痛的方式看來似乎不太可能,我花幾分鐘看了一下架構,那作者不是針對 dataset.FieldByName來hook,我想這是有原因的。它加速的原理不是去改原來的那個FieldByName的演算法,因為可能也沒什麼可加速的,所以才去hook

HookProc(@TFastDataset.DoAfterOpen , @TFastDataset.NewDoAfterOpen , TDatasetDoAfterOpen);
HookProc(@TFastDataset.DoAfterClose , @TFastDataset.NewDoAfterClose, TDatasetDoAfterClose);
HookProc(@TDataset.FindField , @TFastDataset.NewFindField , TDatasetFindField);

這三個方法來「間接」達成任務。實作我完全沒看啦…但架構上看來的感覺是那樣。

「所以DataSet.FieldByName就更好了」,看來是不可行的。
平常還是要養成"良好"的習慣比較重要,我個人在loop中,經常是不用方法來重複的找某個屬性然後改值。我都是設變數(一次工),然後再進loop裡,不只是這個DataSet.FieldByNam,所有這類取物件再設值的事,我都是先在loop外取物件(一次),然後進loop。

過去就給它過去了吧…要看未來比較重要…哈哈
===================引 用 GrandRURU 文 章===================
意思是只要有這個HookTDataset

這樣就不需要GetFieldList(ClientDataSet1)嗎?

如果能夠直上
DataSet.FieldByName就更好了

===================引 用 aftcast 文 章===================
如你有定義 HookDataset_ON_Initialization 這個macro,那麼你就無需要再去執行HookTDataset這個程序,它會在單元載入時就被載入,你去看FieldByNameSpeedUp.pas大的最下面:

initialization
{$IFDEF HookDataset_ON_Initialization}
HookTDataset;
{$ENDIF}

當然,若你想要隨時的調幅原汁原的那個TField,你可以調UnHookTDataset來復原。若程式到了需要再用快速的那個時,就再次調用HookTDataset。但原則上若你覺得這個hook很好用,原則上你應該不會再調用原汁原味的那個,所以作者才會設計一個macro,讓你"自然的"就使用。





===================引 用 GrandRURU 文 章===================
他的HookTDataset / UnHookTDataset這段看的不是很明瞭

不知道這應該怎麼解讀呢?

底下是節錄原文:
I simply managed to hook the TDataset.FindField at runtime and replaced the procedure with my own.
The advantage of this solution if of cause you get the speed instantly. If TFieldyou enable the compiler directive, then Tdataset are hooked on startup, else you'll have to do it you self by calling HookTDataset. If you by some reason wants to restore the original code then this can be done by calling UnHookTDataset.
All the other stuff with GetFieldList etc are of cause still there. So until you get the time/need for refactoring you could use this unit to speed up FieldByname
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#11 引用回覆 回覆 發表時間:2012-11-04 11:53:32 IP:111.249.xxx.xxx 未訂閱
你們這些高手們都在家偷偷練功厚 

我現在有另外一個疑問,有關命名規則

Integer: iNumber
Interface: iFace

前面都是i,有沒有什麼好的識別方法呢?
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#12 引用回覆 回覆 發表時間:2012-11-04 14:18:58 IP:114.44.xxx.xxx 訂閱
nNumber
===================引 用 GrandRURU 文 章===================
你們這些高手們都在家偷偷練功厚

我現在有另外一個疑問,有關命名規則

Integer: iNumber
Interface: iFace

前面都是i,有沒有什麼好的識別方法呢?
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#13 引用回覆 回覆 發表時間:2012-11-05 01:12:20 IP:114.44.xxx.xxx 訂閱
剛喝了酒,仔細看了一下…原來那斜體的英文就是你說的這個意思! (雖然這段斜體的英文寫的不清不楚…好似天外飛來一筆)
應該沒錯,就是若使用hook,就不需要用全域的那個GetFieldList函式。我當時以普通的想法來看,想說他的button有hook,怎麼不會直接用DataSet.FieldByName…

看了leveon的說法與貼文,我才覺得我一定哪裡沒看好…果然…就是你上面說的,有hook就不需要get…。那例子特別寫GetFieldList幹嘛 @@,無意義…

若你過去就用DataSet.FieldByName的寫法,就不可能去用他自己開發的那個GetFieldList函式,因為有更好的寫法不是嗎? 而既然寫到最後有hook,那幹嘛不用hook,讓一切無痛呢? 還要GetFieldList函式做啥@@

一整個就是被他的例子給搞昏了。我現在的結論就是… 「定義macro後,一切就無痛、無感的搞定了」…其他的那個GetFieldList只是實作的過程,沒有直接取用的意義啦!

鳴~~~ 我被騙了~~~

===================引 用 GrandRURU 文 章===================
意思是只要有這個HookTDataset

這樣就不需要GetFieldList(ClientDataSet1)嗎?

如果能夠直上
DataSet.FieldByName就更好了


------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2012-11-04 10:15:52, 註解 無‧
aftcast 重新編輯於 2012-11-04 10:16:37, 註解 無‧
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#14 引用回覆 回覆 發表時間:2012-11-05 06:55:48 IP:111.249.xxx.xxx 未訂閱
 經過了一整夜的測試

一個驚人的發現,效能從高到低排列
Test2 > Test4 = Test3 > Test1

在ATOM牌CPU的處理下
Test2 大約是在 29xx - 3xxx 之間
Test4 大約是在 5xxx - 7xxx 之間
Test1 都是11xxx 以上

不知道為什麼,一旦執行HookTDataset,ClientDataSet的FieldByName就失效了
所以無感升級的方式還沒辦法測

以上
編輯記錄
GrandRURU 重新編輯於 2012-11-04 18:16:20, 註解 無‧
GrandRURU 重新編輯於 2012-11-04 18:17:19, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#15 引用回覆 回覆 發表時間:2012-11-05 16:35:41 IP:114.32.xxx.xxx 訂閱
啊現在這樣是演哪齣? = =

恨不得有裝delphi來測一下…


===================引 用 GrandRURU 文 章===================


不知道為什麼,一旦執行HookTDataset,ClientDataSet的FieldByName就失效了
所以無感升級的方式還沒辦法測

以上
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#16 引用回覆 回覆 發表時間:2012-11-05 23:28:44 IP:111.240.xxx.xxx 訂閱
下載測了一下
function NewFindField(const FieldName: wideString): TField; ==>改成
function NewFindField(const FieldName: String): TField;
把widestring 改成 String 就可以跑了


看起來是無痛

Test1 時間縮短一半 我是把測試程式 改成這樣
計時是在OPEN之後

procedure TForm79.Button1Click(Sender: TObject);
var
Start: DWORD;
i, j: Integer;
begin
ClientDataSet1.Close;
ClientDataSet1.open;
Start := GetTickCount;
Caption := 'running...';
for j := 1 to ROWCOUNT do
begin
ClientDataSet1.Append;
for i := 1 to 10 do
ClientDataSet1.FieldByName('ClientDataSet1Field' IntToStr(i)).AsInteger := i;
ClientDataSet1.Post;
end;
Caption := 'Done in ' IntToStr(GetTickCount - Start);
end;





===================引 用 GrandRURU 文 章===================
經過了一整夜的測試

一個驚人的發現,效能從高到低排列
Test2 > Test4 = Test3 > Test1

在ATOM牌CPU的處理下
Test2 大約是在 29xx - 3xxx 之間
Test4 大約是在 5xxx - 7xxx 之間
Test1 都是11xxx 以上

不知道為什麼,一旦執行HookTDataset,ClientDataSet的FieldByName就失效了
所以無感升級的方式還沒辦法測

以上
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#17 引用回覆 回覆 發表時間:2012-11-06 07:31:17 IP:114.32.xxx.xxx 訂閱
讚!


------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2012-11-05 20:20:33, 註解 無‧
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#18 引用回覆 回覆 發表時間:2012-11-06 09:19:47 IP:59.120.xxx.xxx 未訂閱
二位大大實在太威了

測試結果真的可以用
也可以在Delphi7下施行 (但Test3在D7會編不過)

Test1的確將效能提升到與Test4同速了,不過最快還是Test2 (Test4所耗時間的一半)

最後測試的效能比較
Test2 > Test1=Test4 > Test3


真是受益良多!感謝!
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#19 引用回覆 回覆 發表時間:2012-11-06 10:19:15 IP:114.32.xxx.xxx 訂閱
幫個忙,我想知道一下額外的問題…

function NewFindField(const FieldName: wideString): TField;

上面那一行若「不改」的情形下,哪一個delphi的版本是可用的??
我想應該是某些版可用吧? 不會說無論哪一版的delphi都錯?!

d7,xe?

研究那個是想得到額外的字串比對問題。
手上都沒delphi啦…這串討論我通通用半猜的@@

:p

===================引 用 GrandRURU 文 章===================
二位大大實在太威了

測試結果真的可以用
也可以在Delphi7下施行 (但Test3在D7會編不過)

Test1的確將效能提升到與Test4同速了,不過最快還是Test2 (Test4所耗時間的一半)

最後測試的效能比較
Test2 > Test1=Test4 > Test3


真是受益良多!感謝!
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#20 引用回覆 回覆 發表時間:2012-11-06 10:49:41 IP:118.165.xxx.xxx 訂閱
可能是用這個版本
http://www.marcocantu.com/md2005/UpdateDelphi2006_ch13.html

我也是用猜的 哈哈~~
===================引 用 aftcast 文 章===================
幫個忙,我想知道一下額外的問題…

function NewFindField(const FieldName: wideString): TField;

上面那一行若「不改」的情形下,哪一個delphi的版本是可用的??
我想應該是某些版可用吧? 不會說無論哪一版的delphi都錯?!

d7,xe?

研究那個是想得到額外的字串比對問題。
手上都沒delphi啦…這串討論我通通用半猜的@@

:p

===================引 用 GrandRURU 文 章===================
二位大大實在太威了

測試結果真的可以用
也可以在Delphi7下施行 (但Test3在D7會編不過)

Test1的確將效能提升到與Test4同速了,不過最快還是Test2 (Test4所耗時間的一半)

最後測試的效能比較
Test2 > Test1=Test4 > Test3


真是受益良多!感謝!
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#21 引用回覆 回覆 發表時間:2012-11-06 11:39:02 IP:114.32.xxx.xxx 訂閱
有貼文,猜的好!  呵呵~~

以此亂推2007也是這樣喔!?

這整串研究差不多要告一段落了…

哈…最後我得到的就是這個 2005? 2006與2007?竟然突然變widestring。
不過想想好像也很有道理,d7後可能試著做一些部份unicode的加強吧,但當時沒有unicodestring這個類別,只有widestiring。直到2009,全面unicode話,那麼string就隱含unicode了…於是僅中間有斷層。因d7前也是定義string,只是隱含ansistring…

得到我自認正確的答案了。可以收工了。大家幸苦了 ^_^

最後,只剩ruru說什麼第幾個test在d7下篇不過? 不過我沒d7,沒搞頭,換人接手。


===================引 用 leveon 文 章===================
可能是用這個版本
http://www.marcocantu.com/md2005/UpdateDelphi2006_ch13.html

我也是用猜的 哈哈~~

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#22 引用回覆 回覆 發表時間:2012-11-06 13:08:56 IP:59.120.xxx.xxx 未訂閱
看到副檔名「bdsproj」就知案情必和Borland有關聯,不過我記得2007開始好像就是cdsproj了,應該是2005和2006這兩者其中一個吧
想不到Leveon大還專程貼文上來,真是太感心了!

現在應該已經沒人用 2005~2006了吧
有人要試試嗎?

最後,我說的編不過指的是Test3在「for aField in ClientDataSet1.Fields do」這行,應該是D7的 in 語法還沒被擴展吧

===================引 用 aftcast 文 章===================
有貼文,猜的好! 呵呵~~

以此亂推2007也是這樣喔!?

這整串研究差不多要告一段落了…

哈…最後我得到的就是這個 2005? 2006與2007?竟然突然變widestring。
不過想想好像也很有道理,d7後可能試著做一些部份unicode的加強吧,但當時沒有unicodestring這個類別,只有widestiring。直到2009,全面unicode話,那麼string就隱含unicode了…於是僅中間有斷層。因d7前也是定義string,只是隱含ansistring…

得到我自認正確的答案了。可以收工了。大家幸苦了 ^_^

最後,只剩ruru說什麼第幾個test在d7下篇不過? 不過我沒d7,沒搞頭,換人接手。


===================引 用 leveon 文 章===================
可能是用這個版本
http://www.marcocantu.com/md2005/UpdateDelphi2006_ch13.html

我也是用猜的 哈哈~~

leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#23 引用回覆 回覆 發表時間:2012-11-06 17:51:30 IP:118.165.xxx.xxx 訂閱
看起來 當年的演進 就像是沖哥講的這樣
http://gordonliwei.wordpress.com/2006/01/10/為支援unicode準備-vcl和dbexpress/

那年代的幾個版本 我都沒用過 據說是很難用
大概是改到.net 改壞了

當時Delphi支持.Net 看起來應該是件非做不可的事
現在回頭看 好像是一件蠢事

世事難預料~~


===================引 用 aftcast 文 章===================
有貼文,猜的好! 呵呵~~

以此亂推2007也是這樣喔!?

這整串研究差不多要告一段落了…

哈…最後我得到的就是這個 2005? 2006與2007?竟然突然變widestring。
不過想想好像也很有道理,d7後可能試著做一些部份unicode的加強吧,但當時沒有unicodestring這個類別,只有widestiring。直到2009,全面unicode話,那麼string就隱含unicode了…於是僅中間有斷層。因d7前也是定義string,只是隱含ansistring…

得到我自認正確的答案了。可以收工了。大家幸苦了 ^_^

最後,只剩ruru說什麼第幾個test在d7下篇不過? 不過我沒d7,沒搞頭,換人接手。


===================引 用 leveon 文 章===================
可能是用這個版本
http://www.marcocantu.com/md2005/UpdateDelphi2006_ch13.html

我也是用猜的 哈哈~~

P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#24 引用回覆 回覆 發表時間:2012-11-07 10:15:19 IP:220.136.xxx.xxx 未訂閱
本來事情是很明確的, 不過經過各位大大的說明及經驗測試等等後, L大提供的7篇, 與G大提出的測試及蕭大的說明, 似乎有各自的狀況, 所以不知道是不是能無痛抑或很痛, 而原本G大提出的以TField 方式來解決的技術, 是否有漏洞, 反而我看到更模糊的結論, 不知各位大大有沒有意思可以整合一個簡單的做法提供給後輩的學習者, 不騰感激,
另外, 我在這裡看到使用hook的技術, 我會擔心的是在 win8 的架構上, 是否還有辦法生存下去, 這段我並未研究 win8 的核心, 並不清楚 win8 的作業模式
leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#25 引用回覆 回覆 發表時間:2012-11-07 11:15:32 IP:118.165.xxx.xxx 訂閱
原文提出的方法 當然是效率最高的  

Hook的方式 是無痛的 但效率增進也比較有限

我把檔案放在這 下載回去跑一下就明白了 我是用XE

http://delphi.ktop.com.tw/board.php?cid=31&fid=77&tid=104723

===================引 用 P.D. 文 章===================
本來事情是很明確的, 不過經過各位大大的說明及經驗測試等等後, L大提供的7篇, 與G大提出的測試及蕭大的說明, 似乎有各自的狀況, 所以不知道是不是能無痛抑或很痛, 而原本G大提出的以TField 方式來解決的技術, 是否有漏洞, 反而我看到更模糊的結論, 不知各位大大有沒有意思可以整合一個簡單的做法提供給後輩的學習者, 不騰感激,
另外, 我在這裡看到使用hook的技術, 我會擔心的是在 win8 的架構上, 是否還有辦法生存下去, 這段我並未研究 win8 的核心, 並不清楚 win8 的作業模式
renard
一般會員


發表:3
回覆:43
積分:24
註冊:2007-06-29

發送簡訊給我
#26 引用回覆 回覆 發表時間:2012-11-09 18:29:01 IP:118.99.xxx.xxx 訂閱
AField : TField; // <= line added

真的沒有變快~快一點點而已~

編輯記錄
renard 重新編輯於 2012-11-09 03:33:10, 註解 無‧
老大仔
尊榮會員


發表:78
回覆:837
積分:1088
註冊:2006-07-06

發送簡訊給我
#27 引用回覆 回覆 發表時間:2012-11-12 12:35:08 IP:210.61.xxx.xxx 未訂閱
結果我從四樓開始完全看不懂...嗚嗚嗚(淚奔)
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#28 引用回覆 回覆 發表時間:2012-11-13 10:28:09 IP:211.76.xxx.xxx 訂閱
真的,我也看不懂(畫圈圈

===================引 用 老大仔 文 章===================
結果我從四樓開始完全看不懂...嗚嗚嗚(淚奔)
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#29 引用回覆 回覆 發表時間:2012-11-20 17:26:42 IP:115.80.xxx.xxx 訂閱
簡單的說就是下載leveon所提供的程式碼。
然後把FieldByNameSpeedUp.pas加入你自己的專案中,然後使用條件編譯,定義HookDataset_ON_Initialization。
接著一切都不用改變,重新編譯你的專案,那你原來的專案就會變快六。當然前題是你原專案用了比較差的寫法時有效。

至於FieldByNameSpeedUp.pas的原理是用「自身API hook」的方式。這種hook方式是很局限性的,換句話說它與作業系統無關。它只是把原來borland bpl裡的FieldByName的api換成自己寫的api,但也是在程式載入後修改記憶體裡的api程式段,一旦程式結束,hook就結束了。因此,原來borland bpl裡的那個api完全不受影響。可以完全的放心使用,不會有後遺
症。會受影響的僅限於有加入FieldByNameSpeedUp.pas單元的專案。其他的專案沒有任何的影響。

至於該api hook的技術要了解的話,可能需要一點點的組合語言的基礎。


------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
系統時間:2024-11-21 23:54:30
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!