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

如何快速交換 A, B 2個值

答題得分者是:RaynorPao
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-03-09 16:33:34 IP:61.225.xxx.xxx 未訂閱
做一個小實驗,想知到如何swap可以較快 procedure swap(a,b:string);//耗費 214 procedure swap(var a,b:string);//耗費 173 請問有高手知道更快的方法嗎?例如直接作位址的交換我不會請指導 procedure TForm1.Button1Click(Sender: TObject); procedure swap(var a1, b1:string); var c:string; begin c:=a1; a1:=b1; b1:=c; end; var a,b:string; i:integer; t1,t2:double; begin a:='a'; b:='b'; t1:=gettickcount; for i:=0 to 1000000 do begin swap(a,b); end; t2:=gettickcount; showmessage(floattostr(t2-t1)); end;
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-03-09 20:43:53 IP:61.221.xxx.xxx 未訂閱
引言: 做一個小實驗,想知到如何swap可以較快 procedure swap(a,b:string);//耗費 214 procedure swap(var a,b:string);//耗費 173 請問有高手知道更快的方法嗎?例如直接作位址的交換我不會請指導 procedure TForm1.Button1Click(Sender: TObject); procedure swap(var a1, b1:string); var c:string; begin c:=a1; a1:=b1; b1:=c; end; var a,b:string; i:integer; t1,t2:double; begin a:='a'; b:='b'; t1:=gettickcount; for i:=0 to 1000000 do begin swap(a,b); end; t2:=gettickcount; showmessage(floattostr(t2-t1)); end;
suda 你好: 試試看這樣有沒有比較快呢??(只是演算法,程式碼麻煩你自己寫)
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
ddy
站務副站長


發表:262
回覆:2105
積分:1169
註冊:2002-07-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-03-09 21:14:24 IP:211.74.xxx.xxx 未訂閱
補充RaynorPao 版主所提的 也可以用加、減法來實現交換
a = a + b 
b = a - b
a = a - b
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-03-09 23:45:21 IP:61.217.xxx.xxx 未訂閱
不好意思!我指的是資料的交換,有可能是兩個很大的字串或變數,因為資料大或迴圈多的時候會變慢,例如資料排序. 我看了之前的一些文章,有前輩提到交換兩個變數的位址,可是後來沒有下文了,很可惜. 希望有人可以提供如何傳址交換的方向或拍其他可以加快的方法,
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-03-10 09:53:19 IP:203.73.xxx.xxx 未訂閱
引言: 不好意思!我指的是資料的交換,有可能是兩個很大的字串或變數,因為資料大或迴圈多的時候會變慢,例如資料排序. 我看了之前的一些文章,有前輩提到交換兩個變數的位址,可是後來沒有下文了,很可惜. 希望有人可以提供如何傳址交換的方向或拍其他可以加快的方法,
suda 你好: 既然已經有了演算法,剩下的~~就看個人的應用了 > --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-03-10 10:59:55 IP:61.221.xxx.xxx 未訂閱
謝謝您指導方向 被點通了真是神清氣爽 我已可以作變數的交換,接下來要試試位址的交換.
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-03-10 11:14:36 IP:203.73.xxx.xxx 未訂閱
引言: 謝謝您指導方向 被點通了真是神清氣爽 我已可以作變數的交換,接下來要試試位址的交換.
suda 你好: 能不能夠麻煩你試完以後,把結果貼上來 分享給大家知道,用哪一種方法最快呢?? --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-03-10 20:57:06 IP:61.225.xxx.xxx 未訂閱
因為我還不是很了解,只能提供簡單的範例,看看這程式是傳值快還是傳址快? 先告訴大家答案,是傳值快,我搞不慬.在integer時傳址快,但是string傳值卻怏過傳址一倍的速度,真神奇 procedure TForm1.Button1Click(Sender: TObject); var t1,t2:integer; sa,sb:string; procedure SwapstrByValue(a,b:string); var i:integer; c:string; begin for i:=0 to 10000000 do begin c:=a; a:=b; b:=c; end; end; procedure SwapStrByVar(var a,b:string); var i:integer; c:string; begin for i:=0 to 10000000 do begin c:=a; a:=b; b:=c; end; end; begin sa:='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; sb:='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; t1:=gettickcount; swapstrByvalue(sa,sb); t2:=gettickcount; ListBox1.Items.add('SwapStrByValue:' floattostr(t2-t1)); t1:=gettickcount; swapstrByvar(sa,sb); t2:=gettickcount; ListBox1.Items.add('SwapStrByVar:' floattostr(t2-t1)); end; 我試過交換位址,可是結果都不變,是不是交換位址沒有意義,以下的語法決對是錯的,只是我想表達想法 a:='很大的字串'; b:='也是很大的字串'; c:=@a; @a:=@b @b:=par(c); RaynorPao 前輩,可否有相關資料說明delphi資料傳遞,因為我愈深入愈覺得有趣
aip999
初階會員


發表:10
回覆:63
積分:44
註冊:2002-03-29

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-03-13 18:42:53 IP:218.187.xxx.xxx 未訂閱
引言: 因為我還不是很了解,只能提供簡單的範例,看看這程式是傳值快還是傳址快? 先告訴大家答案,是傳值快,我搞不慬.在integer時傳址快,但是string傳值卻怏過傳址一倍的速度,真神奇 procedure TForm1.Button1Click(Sender: TObject); var t1,t2:integer; sa,sb:string; procedure SwapstrByValue(a,b:string); var i:integer; c:string; begin for i:=0 to 10000000 do begin c:=a; a:=b; b:=c; end; end; procedure SwapStrByVar(var a,b:string); var i:integer; c:string; begin for i:=0 to 10000000 do begin c:=a; a:=b; b:=c; end; end; begin sa:='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; sb:='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; t1:=gettickcount; swapstrByvalue(sa,sb); t2:=gettickcount; ListBox1.Items.add('SwapStrByValue:' floattostr(t2-t1)); t1:=gettickcount; swapstrByvar(sa,sb); t2:=gettickcount; ListBox1.Items.add('SwapStrByVar:' floattostr(t2-t1)); end; 我試過交換位址,可是結果都不變,是不是交換位址沒有意義,以下的語法決對是錯的,只是我想表達想法 a:='很大的字串'; b:='也是很大的字串'; c:=@a; @a:=@b @b:=par(c); RaynorPao 前輩,可否有相關資料說明delphi資料傳遞,因為我愈深入愈覺得有趣
@@是傳址快吧,你試試只有3 行ccc procedure SwapStrByPtr(var a,b:string); asm xchg ecx,dword ptr [eax] xchg ecx,dword ptr [edx] xchg ecx,dword ptr [eax] end; pascal 的語法 var c : pointer; procedure SwapStrByPtr(var a,b:string); begin c:=Pointer(a); Pointer(a):=Pointer(b); Pointer(b):=c; end; { /////// procedure SwapStrByPtr(var a,b:string); asm //1: // mov ecx,dword ptr [eax] // mov dword ptr [c],ecx // mov ecx,dword ptr [edx] // mov dword ptr [eax],ecx // mov ecx,dword ptr [c] // mov dword ptr [eax],ecx //2: // push dword ptr [eax] // push dword ptr [edx] // pop dword ptr [eax] // pop dword ptr [edx] //3: // xchg ecx,dword ptr [eax] // xchg ecx,dword ptr [edx] // xchg ecx,dword ptr [eax] end; } 發表人 - aip999 於 2003/03/13 20:52:03
00156
高階會員


發表:45
回覆:195
積分:112
註冊:2002-06-01

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-03-13 21:18:31 IP:61.56.xxx.xxx 未訂閱
引言: 因為我還不是很了解,只能提供簡單的範例,看看這程式是傳值快還是傳址快? 先告訴大家答案,是傳值快,我搞不慬.在integer時傳址快,但是string傳值卻怏過傳址一倍的速度,真神奇
你不妨做個實驗:
var s:string;
begin
  s:='A real long string...';
  ShowMessage(IntToStr(SizeOf(s)));
end;
把上面的宣告改為s:shortstring試試看,結果很不同。 string type 只是存放4個位元組的位址,shortstring type才是255位元組的實體,因此你的實驗仍舊只是"傳址"。對於string變數的交換,在Delphi內部應該都是傳址的。影響速度比較大的因素應該是procedure建構時傳址或傳值(傳值時要再取得一個完整實體,理論上比較慢吧)。因此,你的試驗迴圈不妨放在呼叫的地方,不要放在procedure裡,才能測得這部份的速度差異。 有趣的是,integer(4 bytes), byte(1 byte), real(8 bytes)等變數都是記錄實際的大小,只有string不太一樣,內部大概是用和PChar相同的方式來記錄資料的。
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-03-14 19:26:42 IP:61.217.xxx.xxx 未訂閱
aip999  你真是令我驚訝! 連asm的技術都出來了我試過後果然不一樣,(ㄉㄞ/)一下就出來了,很感謝你的幫助 我真是吻仔魚游大海~~   ,,,,,,, (@ @) ,\@/   哇~~~~~  好大的海呀 可惜分數己給人了,下次要早一點自己自首,好唄! 說正經的,第一種和第三種有何不同 這方法我用
系統時間:2024-05-03 19:08:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!