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

更快速的 Split 功能和對應的 Join 功能

 
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-17 20:48:48 IP:218.16.xxx.xxx 未訂閱
[在電子報001期發表,現在討論區補貼]    一般來說, Split 功能主要是將一個字串按特定的分隔符號來分開成 Array,而 Join 功能就是將一個 Array 以特定的分隔符號來隔開組成一個字串,方便儲存。    由於Delphi 的 Dynamic Array 功能比較弱而問題多多,所以很多時我們會以 StringList 來代替。    這裡提供的就是將 String Split 成 StringList 的 FastSplit 函數和 將 StringList Join 成 String 的 FastJoin 函數。    其實,在 K.Top 網站之前已有網友Dalman提供過一個 _Split 函數,功能是一樣的,亦看見有其他網友不斷沿用這個函數,詳情可見 :    http://delphi.ktop.com.tw/topic.php?topic_id=21331    那為甚麼還來發表這篇文章,難道是騙稿費? 第一,在這裡發表沒稿費的耶。 第二,原文沒有相對的 Join 功能。 第三,_Split 功能比小弟的拙作 FastSplit 要耗用多 50% 的時間。    癈話少說,就看看這兩個功能的程式碼罷 :    
function FastSplit(const S : String; const Delimiter : String=',') : TStrings;
var
  i,j : integer;
begin
  result := TStringList.Create;
  i := 1;
  j := Pos(Delimiter,S);
  While j > 0 do
  begin
    result.Add(Copy(S,i,j-i));
    i := j   1;
    j := PosEx(Delimiter,S,i);
  end;
  result.Add(Copy(S,i,Length(S)));
end;
 
function FastJoin(SL : TStrings; const Delimiter : String=',') : String;
begin
  result := StringReplace(SL.Text,#13#10,Delimiter,[rfReplaceAll]);
  result := copy(result,1,length(result)-1);
end;
 
 
速度測試 :
 
Split 測試 : 
將 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z' 用兩個不同的 Split 函數拆開 10000 次。
 
FastSplit                : 0.17 秒
_Split                        : 0.26 秒
wordwrap                : 0.56 秒 (每個還剩','在尾部,若刪除共要差不多2秒)
 
Join 測試 : 
先將 Split 測試的結果放在 TMemo ,然後用 Memo.Lines 來給 Join 函數結合 10000 次。
 
FastJoin                : 0.73 秒
 
 
老實說,我對 FastJoin 的速度並不滿意,沒理由結合比分拆慢那麼多。我試過幾個不同的做法:
 
像 FastJoin 那樣用迴圈將每行的值加在一起        : 0.87 秒
用 SL.Delimiter 及 SL.DelimitedText        : 1 秒多
 
各讀者們又有沒有更好的方法呢?希望你們能將你們更好的方法與我但一同分享。 註:速度會因應電腦不同而有所不冋,主要是對不同方法作比較之用。 發表人 - Justmade 於 2003/04/17 21:52:15
ying0515
中階會員


發表:90
回覆:168
積分:81
註冊:2003-01-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-17 23:48:42 IP:218.165.xxx.xxx 未訂閱
值得學習! Delphi Man
------
Delphi
zong
初階會員


發表:11
回覆:51
積分:42
註冊:2002-08-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-18 08:43:17 IP:61.219.xxx.xxx 未訂閱
哇! 精神可佳! 說真的程式師一般只會找到可用的方法就一直沿用下去! 會從這些方法中 比較 測試 尋求更好的 才是一個好的設程師!
jasver
一般會員


發表:4
回覆:11
積分:3
註冊:2002-04-03

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-22 11:34:01 IP:140.92.xxx.xxx 未訂閱
可不可以把你的測試程式上傳 因為我也做了一個測試程式 但是不知道你的PosEx的函數內容是什麼 所以我假設是下列的函數 function TForm1.PosEx(Substr: string; S: string; P: Integer): Integer; begin if P <= 0 then Result := 0 else Result := Pos(Substr, Copy(S, P, Length(S))); if Result <> 0 then Result := Result P - 1; end; 但是我測試的結果卻是_Split比較快 所以請問你的PosEx是否不一樣
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-22 12:10:24 IP:218.16.xxx.xxx 未訂閱
PosEx is build in function you have to use StrUtil(or StrUtils? I dont have delphi now)
jasver
一般會員


發表:4
回覆:11
積分:3
註冊:2002-04-03

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-22 13:05:49 IP:140.92.xxx.xxx 未訂閱
對不起我是用d6的所以沒有哪個函數 我把d7裡的函數拿過來用之後 的確是快非常多
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-05-07 12:21:29 IP:218.16.xxx.xxx 未訂閱
From Delphi 7 VCL
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer; 
var
  I,X: Integer;
  Len, LenSubStr: Integer;
begin
  if Offset = 1 then
    Result := Pos(SubStr, S)
  else
  begin
    I := Offset;
    LenSubStr := Length(SubStr);
    Len := Length(S) - LenSubStr   1;
    while I <= Len do
    begin
      if S[I] = SubStr[1] then
      begin
        X := 1;
        while (X < LenSubStr) and (S[I   X] = SubStr[X   1]) do
          Inc(X);
        if (X = LenSubStr) then
        begin
          Result := I;
          exit;
        end;
      end;
      Inc(I);
    end;
    Result := 0;
  end;
end;
發表人 - Justmade 於 2003/05/07 12:22:44
系統時間:2024-05-04 22:38:54
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!