全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4349
推到 Plurk!
推到 Facebook!

字串比較(與 TStringList 內部所採用方式)

答題得分者是:danny
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-10-10 11:59:35 IP:61.64.xxx.xxx 訂閱
[code delphi]
function TStringList.CompareStrings(const S1, S2: string): Integer;

begin

if CaseSensitive then

Result := AnsiCompareStr(S1, S2) //** ---> 最後會叫 API --> CompareStringA

else

Result := AnsiCompareText(S1, S2);

end;
[/code]
  1. 當區分大小寫時
    為何不使用 Result := S1 = S2;
    難道 Delphi 的字串比較會比 API 的慢?還是說有什麼原因一定要使用 API ?
  2. 當區分大小寫時,就跟比較兩記憶體區塊無異,因此若使用 CompareMem,是否更快?

    SysUtils 哪有著不只一個的字串比較函式,每個的演算法,都不同,為一相同的是都有 S1 與 S2
    只是字串比較而已,為何出現如此多的函式?不知大家是否有思考過?
  3. 就算是需要因應不同場合,其基本的演算法則也應該相同,出現如此多的版本,常常讓新手選到頭暈,不知大家都如何選擇字串比較函式,還是說,隨便選一個用?


編輯記錄
taishyang 重新編輯於 2007-10-11 10:11:20, 註解 無‧
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-10-15 18:10:20 IP:203.79.xxx.xxx 訂閱
>當區分大小寫時
>為何不使用 Result := S1 = S2;
>難道 Delphi 的字串比較會比 API 的慢?還是說有什麼原因一定要使用 API ?

當區分大小寫時是可以使用 Result := S1 = S2; 啊!
AnsiCompareStr 的 Help 說明是 Compares strings based on the current Windows locale with case sensitivity.
這樣應該很清楚 AnsiCompareStr 使用的地方


>當區分大小寫時,就跟比較兩記憶體區塊無異,因此若使用 CompareMem,是否更快?
>SysUtils 哪有著不只一個的字串比較函式,每個的演算法,都不同,為一相同的是都有 S1 與 S2
>只是字串比較而已,為何出現如此多的函式?不知大家是否有思考過?

CompareMem 的宣告如下, 會比較容易使用嗎? 至少不夠直覺還需指定長度(String[0]是記錄字串的長度), 而且也不見得比較快, 因為 Delphi 的自串比較說不定是包裝 CompareMem 起來的
function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;

至於 Delphi 為何出現如此多的字串比較函式, 請你看一下 AnsiCompareStr, AnsiCompareText 的程式內容應該比較容易理解

function AnsiCompareStr(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), Length(S1),
PChar(S2), Length(S2)) - 2;
end;

function AnsiCompareText(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1),
Length(S1), PChar(S2), Length(S2)) - 2;
end;


>就算是需要因應不同場合,其基本的演算法則也應該相同,出現如此多的版本,常常讓新手選到頭暈,不知大家都如何選擇字串比較函式,還是說,隨便選一個用?

這要看使用的用途而定

===================引 用 syntax 文 章===================
[code delphi]
function TStringList.CompareStrings(const S1, S2: string): Integer;

begin

if CaseSensitive then

Result := AnsiCompareStr(S1, S2) //** ---> 最後會叫 API --> CompareStringA

else

Result := AnsiCompareText(S1, S2);

end;
[/code]
  1. 當區分大小寫時
    為何不使用 Result := S1 = S2;
    難道 Delphi 的字串比較會比 API 的慢?還是說有什麼原因一定要使用 API ?
  2. 當區分大小寫時,就跟比較兩記憶體區塊無異,因此若使用 CompareMem,是否更快?

    SysUtils 哪有著不只一個的字串比較函式,每個的演算法,都不同,為一相同的是都有 S1 與 S2
    只是字串比較而已,為何出現如此多的函式?不知大家是否有思考過?
  3. 就算是需要因應不同場合,其基本的演算法則也應該相同,出現如此多的版本,常常讓新手選到頭暈,不知大家都如何選擇字串比較函式,還是說,隨便選一個用?

------
將問題盡快結案也是一種禮貌!
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-10-16 09:11:31 IP:61.64.xxx.xxx 訂閱
感謝你的回應,但並沒有真的回答到我想知道的東西,我想我的問題不夠準確,因為我也有點混亂,不知道該問什麼,無法切卻切入問題核心

CompareMem 是由 Mozilla 來的,用的是組語,而 Delphi 的字串比較,到底是包裝什麼?,追一下就知道拉,不需要猜測,我這邊看到的是呼叫 LStrCmp(),同時,若是在比較時,就已知長度(例如傳入比較長度),當然會比較快,比運作時再去計算長度快(省了計算長度的時間),但是如果只是拿到函數外面計算,那與在內計算,是沒有差異的(一樣快)

Delphi 為何出現如此多的字串比較函式, 請你看一下 AnsiCompareStr, AnsiCompareText 的程式內容應該比較容易理解
那些如何使用函式的解答,並不是我想知道的,對於看說明文件可以知道的東西,不是我主要的目的
我想知道的是為何相同參數,相同用途的同一種函式,Delphi 會有兩種寫法,如果依據效率來看,不是應該只有一種方式最快的嗎?(不然就是一樣快)
我也當然知道
<basefont></basefont>The compare operation is controlled by the current locale
But How ? that is the answer i want !


所以這裡我的問題,我想應該變得比較清楚了

  1. controlled by the current locale,是如何的運作方式?
  2. TStrings 並沒有提供 locale 的相關程序,所以,今天,如果使用「你好嗎?」,並使用不同 locale,存入 S1 與 S2
    比較時 AnsiCompareStr 會自動幫我轉換,並跟我說是一樣的字串嗎?
    如果不是,為何用之直接使用 S1 = S2 判斷不就好了嗎?
  3. 我的看法比較簡單,字串不過是存放在記憶體內的資料,當每個位址的數值都一樣,則兩字串相等,如此狀況下,如果比較時不會自動轉碼,則與比較記憶體無異,所以在區分大小寫的狀況下, S1 := S2 或 CompareMem 不是比較快?
  4. 同時我也想知道 S1 := S2 或 CompareMem 誰快,還是說有另外的組語語法可以更快?
  5. 為何相同參數,相同用途的同一種函式,Delphi 會有兩種寫法,請參考 StrComp 與 CompareStr 的第一種型態 (不使用 locale 的那種) ,CompareStr 的比較簡潔,當然這裡必須要注意的是,StrComp 所使用的是 PChar,為了記錄誰長誰短,所以必須付出額外的紀錄空間與運作時間(而 String 因為設計關係,已經記錄過長度,勿需在計算一次),但是,撇開此機制,單看其字串比較的部分,並不相同,知道 String 與 PChar 差異的人,應該知道,兩者的差異很少,轉換成本也很低,那為何要有 StrComp 與 CompareStr兩種不同的設計?如果 CompareStr 真的那麼好,那將 StrComp 轉成 String 再來呼叫 CompareStr 不就好了?如考慮 PChar --> String 會比較耗時,那用 String --> PChar ,反過來 CompareStr 去呼叫 StrComp,不需要兩者都做成一個實體的函式,有誰可以說明一下?
  6. 另外,有趣的是,找不到 SameStr 的說明,只有 SameText 的說明,然而兩者在設計上,是一樣的呼叫流程 SameXXX call CompareXXX,Delphi 不希望有人用 SameStr ?<basefont></basefont>
===================引 用 danny 文 章===================
>當區分大小寫時
>為何不使用 Result := S1 = S2;
>難道 Delphi 的字串比較會比 API 的慢?還是說有什麼原因一定要使用 API ?

當區分大小寫時是可以使用 Result := S1 = S2; 啊!
AnsiCompareStr 的 Help 說明是 Compares strings based on the current Windows locale with case sensitivity.
這樣應該很清楚 AnsiCompareStr 使用的地方


>當區分大小寫時,就跟比較兩記憶體區塊無異,因此若使用 CompareMem,是否更快?
>SysUtils 哪有著不只一個的字串比較函式,每個的演算法,都不同,為一相同的是都有 S1 與 S2
>只是字串比較而已,為何出現如此多的函式?不知大家是否有思考過?

CompareMem 的宣告如下, 會比較容易使用嗎? 至少不夠直覺還需指定長度(String[0]是記錄字串的長度), 而且也不見得比較快, 因為 Delphi 的自串比較說不定是包裝 CompareMem 起來的
function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;

至於 Delphi 為何出現如此多的字串比較函式, 請你看一下 AnsiCompareStr, AnsiCompareText 的程式內容應該比較容易理解

function AnsiCompareStr(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), Length(S1),
PChar(S2), Length(S2)) - 2;
end;

function AnsiCompareText(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1),
Length(S1), PChar(S2), Length(S2)) - 2;
end;


>就算是需要因應不同場合,其基本的演算法則也應該相同,出現如此多的版本,常常讓新手選到頭暈,不知大家都如何選擇字串比較函式,還是說,隨便選一個用?

這要看使用的用途而定

===================引 用 syntax 文 章===================
[code delphi]
function TStringList.CompareStrings(const S1, S2: string): Integer;

begin

if CaseSensitive then

Result := AnsiCompareStr(S1, S2) //** ---> 最後會叫 API --> CompareStringA

else

Result := AnsiCompareText(S1, S2);

end;
[/code]
  1. 當區分大小寫時
    為何不使用 Result := S1 = S2;
    難道 Delphi 的字串比較會比 API 的慢?還是說有什麼原因一定要使用 API ?
  2. 當區分大小寫時,就跟比較兩記憶體區塊無異,因此若使用 CompareMem,是否更快?

    SysUtils 哪有著不只一個的字串比較函式,每個的演算法,都不同,為一相同的是都有 S1 與 S2
    只是字串比較而已,為何出現如此多的函式?不知大家是否有思考過?
  3. 就算是需要因應不同場合,其基本的演算法則也應該相同,出現如此多的版本,常常讓新手選到頭暈,不知大家都如何選擇字串比較函式,還是說,隨便選一個用?
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-10-16 23:51:39 IP:203.79.xxx.xxx 訂閱
你的問題很有趣, 不過我無法解答你的疑惑 
不過這看起來比較像是歷史留下的痕跡, Delphi 1.0 (16Bit) -> Delphi 3.x(32Bit) -> Delphi X (架構有變)
也許要找到之前的 Delphi 版本(說不定還有說明文件)來比較才能知道吧!
如果你可以的話, 可以追一下 DBGrid source code 幾乎每一個 Delphi 版本都有很大的內部架構變動.

===================引 用 syntax 文 章===================
感謝你的回應,但並沒有真的回答到我想知道的東西,我想我的問題不夠準確,因為我也有點混亂,不知道該問什麼,無法切卻切入問題核心

CompareMem 是由 Mozilla 來的,用的是組語,而 Delphi 的字串比較,到底是包裝什麼?,追一下就知道拉,不需要猜測,我這邊看到的是呼叫 LStrCmp(),同時,若是在比較時,就已知長度(例如傳入比較長度),當然會比較快,比運作時再去計算長度快(省了計算長度的時間),但是如果只是拿到函數外面計算,那與在內計算,是沒有差異的(一樣快)

Delphi 為何出現如此多的字串比較函式, 請你看一下 AnsiCompareStr, AnsiCompareText 的程式內容應該比較容易理解
那些如何使用函式的解答,並不是我想知道的,對於看說明文件可以知道的東西,不是我主要的目的
我想知道的是為何相同參數,相同用途的同一種函式,Delphi 會有兩種寫法,如果依據效率來看,不是應該只有一種方式最快的嗎?(不然就是一樣快)
我也當然知道
<basefont></basefont>The compare operation is controlled by the current locale
But How ? that is the answer i want !


所以這裡我的問題,我想應該變得比較清楚了

  1. controlled by the current locale,是如何的運作方式?
  2. TStrings 並沒有提供 locale 的相關程序,所以,今天,如果使用「你好嗎?」,並使用不同 locale,存入 S1 與 S2
    比較時 AnsiCompareStr 會自動幫我轉換,並跟我說是一樣的字串嗎?
    如果不是,為何用之直接使用 S1 = S2 判斷不就好了嗎?
  3. 我的看法比較簡單,字串不過是存放在記憶體內的資料,當每個位址的數值都一樣,則兩字串相等,如此狀況下,如果比較時不會自動轉碼,則與比較記憶體無異,所以在區分大小寫的狀況下, S1 := S2 或 CompareMem 不是比較快?
  4. 同時我也想知道 S1 := S2 或 CompareMem 誰快,還是說有另外的組語語法可以更快?
  5. 為何相同參數,相同用途的同一種函式,Delphi 會有兩種寫法,請參考 StrComp 與 CompareStr 的第一種型態 (不使用 locale 的那種) ,CompareStr 的比較簡潔,當然這裡必須要注意的是,StrComp 所使用的是 PChar,為了記錄誰長誰短,所以必須付出額外的紀錄空間與運作時間(而 String 因為設計關係,已經記錄過長度,勿需在計算一次),但是,撇開此機制,單看其字串比較的部分,並不相同,知道 String 與 PChar 差異的人,應該知道,兩者的差異很少,轉換成本也很低,那為何要有 StrComp 與 CompareStr兩種不同的設計?如果 CompareStr 真的那麼好,那將 StrComp 轉成 String 再來呼叫 CompareStr 不就好了?如考慮 PChar --> String 會比較耗時,那用 String --> PChar ,反過來 CompareStr 去呼叫 StrComp,不需要兩者都做成一個實體的函式,有誰可以說明一下?
  6. 另外,有趣的是,找不到 SameStr 的說明,只有 SameText 的說明,然而兩者在設計上,是一樣的呼叫流程 SameXXX call CompareXXX,Delphi 不希望有人用 SameStr ?<basefont></basefont>
===================引 用 danny 文 章===================
>當區分大小寫時
>為何不使用 Result := S1 = S2;
>難道 Delphi 的字串比較會比 API 的慢?還是說有什麼原因一定要使用 API ?

當區分大小寫時是可以使用 Result := S1 = S2; 啊!
AnsiCompareStr 的 Help 說明是 Compares strings based on the current Windows locale with case sensitivity.
這樣應該很清楚 AnsiCompareStr 使用的地方


>當區分大小寫時,就跟比較兩記憶體區塊無異,因此若使用 CompareMem,是否更快?
>SysUtils 哪有著不只一個的字串比較函式,每個的演算法,都不同,為一相同的是都有 S1 與 S2
>只是字串比較而已,為何出現如此多的函式?不知大家是否有思考過?

CompareMem 的宣告如下, 會比較容易使用嗎? 至少不夠直覺還需指定長度(String[0]是記錄字串的長度), 而且也不見得比較快, 因為 Delphi 的自串比較說不定是包裝 CompareMem 起來的
function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;

至於 Delphi 為何出現如此多的字串比較函式, 請你看一下 AnsiCompareStr, AnsiCompareText 的程式內容應該比較容易理解

function AnsiCompareStr(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), Length(S1),
PChar(S2), Length(S2)) - 2;
end;

function AnsiCompareText(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1),
Length(S1), PChar(S2), Length(S2)) - 2;
end;


>就算是需要因應不同場合,其基本的演算法則也應該相同,出現如此多的版本,常常讓新手選到頭暈,不知大家都如何選擇字串比較函式,還是說,隨便選一個用?

這要看使用的用途而定

===================引 用 syntax 文 章===================
[code delphi]
function TStringList.CompareStrings(const S1, S2: string): Integer;

begin

if CaseSensitive then

Result := AnsiCompareStr(S1, S2) //** ---> 最後會叫 API --> CompareStringA

else

Result := AnsiCompareText(S1, S2);

end;
[/code]
  1. 當區分大小寫時
    為何不使用 Result := S1 = S2;
    難道 Delphi 的字串比較會比 API 的慢?還是說有什麼原因一定要使用 API ?
  2. 當區分大小寫時,就跟比較兩記憶體區塊無異,因此若使用 CompareMem,是否更快?

    SysUtils 哪有著不只一個的字串比較函式,每個的演算法,都不同,為一相同的是都有 S1 與 S2
    只是字串比較而已,為何出現如此多的函式?不知大家是否有思考過?
  3. 就算是需要因應不同場合,其基本的演算法則也應該相同,出現如此多的版本,常常讓新手選到頭暈,不知大家都如何選擇字串比較函式,還是說,隨便選一個用?
------
將問題盡快結案也是一種禮貌!
系統時間:2024-04-29 10:36:37
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!