字符串里包含很多空格"aa bb ee dd ff 2332 898f 2e 23",有什摸好办法快速删除? ( 积分: 10 )

  • 主题发起人 主题发起人 xydrj
  • 开始时间 开始时间
好热闹哦
--------------------------------------------------------------------------------
来自:kinneng, 时间:2005-7-5 1:35:36, ID:3124122
科学地判断一段程序的快慢,应该查阅这段程序编译后的执行代码,然后根据这些汇编指令运行周期,累计算出运行时间,方可说明问题,而且只有这样,才可以排除测试环境差异的影响,排除外界干扰的影响,特别是Windows这种复杂环境下产生的各种影响,而且只有用这种方法才有说服力,有没有道理请各位自己参详,不说了。

我关心的是分,上大富翁就是要分,这里除了分,可以说什么都没有,我问的问题没有答案,买书也没优惠,楼主的要求是将空格分开的16进制数据转成10进制,所有人都是问非所答的,而我是唯一肯去回答这个问题的人,我要分一点不过份,呵呵,不是吗?
--------------------------------------------------------------------------------
我强烈同意,但是我要说的是,分要要,问题也要讨论(还有没有更好的办法?)。
楼主好象消失了,哈哈哈哈。
 
呵呵,什么时候变得这么深入了,有点晕
 
to:kinneng

不要动不动就拿汇编砸人呵,编译器优化后的汇编未必会比你等手工掰的汇编效率差,问题稍微复杂点你就掰不过编译器了,问题很复杂的时候再牛的人也掰不过编译器呵。

我最讨厌别人说汇编比C效率高,C比PASCAL效率高了,一点技术含量都没有!
 
jshyhzj 我是中间派,你也不要这么极端,现在不是我读书少,就谁都管不了我的时代,复杂问题与程序优化是两回事,复杂问题编译之后,还可以将里面某些细节,通过改用汇编来优化,任何高级语言都一样,连delphi自己也是这样干活的。
 
汇编学过,但没用过,基本和不会一样,kinneng说的没错,但你并没有把pascal的代码生成的汇编拿出来做比较啊,你写的汇编就一定比d翻译的汇编更优化吗?测试数据也是很好的一个证明,最终验证理论的还是实际数据,在相同环境下,大量的数据得出相近的结果,那我为什么不相信数据呢?

代码:
procedure ss(var s:string);
var
i,j:integer;
p: pchar;
begin
p:= pchar(s);
j := length(s) - 1;
for i := 0 to j do
if p =' ' then
begin
j := i;
BREAK;
end;

for i := j + 1 to length(s) - 1 do
begin
if p<>' ' then
begin
p[j] := p;
inc(j);
end;
end;
setlength(s,j);
end;

function Kill32(StrPoint:Pointer; StrLong:Integer):Integer;
asm
PUSH EDI //保留这些寄存器进栈
PUSH ESI
PUSH EBX
MOV EDI,EAX //设置目标和源指针,指向字串的第一个字节
MOV ESI,EAX
MOV ECX,StrLong //设置循环长度,即字串长度
XOR EBX,EBX //初始化目标长度计数器,记录字串处理后的长度
@@J2: //循环体开始
MOV AL,[ESI] //取一个字节
CMP AL, 32 //32是空格的编码
JZ @@J1 //是空格则跳过,不处理
MOV [EDI],AL //非空格,则保存到目标指针的位置
INC EDI //目标指针加一
INC EBX //目标长度计数器加一
@@J1:
INC ESI //源指针加一
LOOP @@J2 //执行循环体
MOV RESULT,EBX //返回处理后字串的长度
POP EBX //从栈中恢复寄存器
POP ESI
POP EDI
end;

procedure ss1(var s:string);
var
i,j:integer;
p:pchar;
begin
if integer(s)=0 then exit;
j := 0;
p := pchar(s);
for i := 0 to pinteger(integer(s)-4)^ do
begin
if p<>' ' then
begin
p[j] := p;
inc(j);
end;
end;
setlength(s,j);
end;

procedure ss2(var s:string);
var
i,j:integer;
p:pchar;
begin
j := 0;
p := pchar(s);
for i := 0 to pinteger(integer(s)-4)^ do
begin
if p<>' ' then
begin
p[j] := p;
inc(j);
end;
end;
setlength(s,j);
end;

200次测试数据:

ss
591 600 600 601
590 601 591 601
611 601 591 601
591 591 601 591
601 590 600 591
590 581 591 601
591 601 581 601
601 601 591 600
621 610 600 591
600 591 611 591
591 591 611 601
581 601 591 600
601 600 590 611
601 601 601 591
601 591 601 611
601 591 601 610
591 601 591 601
611 601 591 591
601 591 601 591
601 591 591 600
590 591 591 601
591 591 591 601
601 601 601 591
601 590 611 590
590 581 601 601
611 621 591 611
601 601 611 601
601 601 601 590
590 591 601 601
591 591 601 601
591 591 591 601
601 600 591 610
600 601 591 601
591 611 611 601
591 591 601 591
591 590 591 601
601 591 611 591
601 601 601 591
591 591 591 611
580 610 581 600
591 601 591 601
601 601 601 591
621 591 601 591
601 590 621 601
591 601 591 601
601 601 591 601
601 601 601 601
600 580 601 601
601 581 601 631
591 601 591 591

597.42 596.2 597.52 599.44

--------------------------

kill32
801 811 811 801
811 811 811 801
801 831 811 811
811 811 811 801
791 821 811 801
811 801 801 841
821 811 812 821
801 821 812 811
801 801 802 811
801 811 831 821
811 811 811 791
801 812 801 811
812 812 801 831
822 812 811 811
812 812 811 801
802 802 811 801
801 801 821 812
811 821 811 802
801 811 811 812
811 811 801 812
811 801 811 811
811 811 811 811
991 801 801 811
912 801 811 811
891 821 801 801
831 811 811 811
811 811 802 811
811 801 812 801
821 821 812 821
801 801 801 801
801 801 831 801
801 821 841 811
811 811 861 801
821 801 861 811
821 802 861 821
812 812 842 811
792 802 802 801
802 811 802 821
811 891 811 812
811 1061 821 802
821 822 801 802
831 822 811 831
811 801 811 801
801 811 801 801
801 801 791 811
811 811 811 801
811 801 831 801
811 811 821 821
801 811 801 811
811 831 811 801

816.36 817 813.98 809.34

--------------------------

ss1
641 641 651 631
631 641 641 631
631 641 621 631
641 641 641 640
641 641 661 641
641 631 641 641
631 631 631 641
621 641 641 640
641 641 631 641
661 661 641 631
631 641 641 631
631 641 641 641
641 641 651 641
641 641 641 651
641 631 641 631
631 631 641 630
631 681 641 641
641 661 641 641
651 630 641 641
641 641 651 641
631 641 661 651
631 641 631 651
651 630 641 641
641 641 641 631
631 641 641 651
631 641 631 641
661 661 631 641
641 641 641 641
641 631 651 641
631 641 641 641
631 641 631 641
641 631 640 651
641 631 631 631
641 641 641 631
651 671 631 641
641 651 630 641
641 641 641 651
641 631 651 631
621 641 641 641
631 641 641 641
641 631 631 641
641 631 641 651
641 641 641 641
631 641 630 641
631 641 641 651
641 621 651 641
631 631 641 641
631 641 641 631
631 641 631 641
641 641 641 661

637.8 640.76 640.14 640.54

--------------------------

ss2
571 571 571 571
581 581 571 570
561 561 561 571
561 560 560 571
561 571 571 570
561 571 581 571
570 570 570 571
601 581 571 571
571 571 591 561
570 570 761 561
561 571 581 561
561 571 580 581
580 570 571 571
571 571 561 571
571 591 570 571
570 571 571 560
581 571 571 561
561 561 560 561
560 561 571 570
581 581 561 571
571 561 560 571
571 571 561 560
571 571 581 571
561 580 561 561
571 561 571 560
581 561 571 571
571 570 561 571
571 571 561 581
561 571 561 561
561 560 571 561
561 561 591 571
561 571 571 571
591 590 561 571
581 571 561 571
571 581 560 571
571 570 571 561
571 561 571 561
561 561 570 561
560 571 561 570
571 581 571 571
571 571 570 571
571 591 571 581
561 571 591 561
561 551 570 561
560 561 571 560
581 571 571 591
561 570 551 571
570 571 561 570
571 571 581 571
561 581 571 571

569.24 570.6 573.2 568.42

king.gray 提供的 FastReplace 没有成绩,因为出错:
// 找到了, 返回找到的地址, 并修改SrcCount变量(已经去掉了匹配字符串的长度)
DEC EDX // 程序开始时多算一个字节, 现在去掉
MOV SrcCount, EDX //<-到这行出错

是否提供的代码有误?我是d5。

来自:jshyhzj, 时间:2005-7-4 17:39:52, ID:3123850
for i := 0 to pinteger(integer(s)-4)^ do //传一个空串你在这儿就死翘翘拉!!!

测试了下pinteger(integer(s)-4)^和length,对一字符串取长度,取10000000次,累计时间前者只用后者1/4时间,对于空串,判断一次即可,也做了测试,加了对空串判断的代码后,比pinteger(integer(s)-4)^是慢,但仍比length快许多。

但不幸的是,ss1和ss2的代码就差一个if,但速度差好多,不解。

另外,jshyhzj,ss还是比不上ss2,看了ss1和ss2的差别,应该也好理解为什么ss会慢。

kinneng,你有什么超高难度问题呀?在这里,如果是有趣的问题,没有分数高手们也乐意参与,这里的分数只对新人有吸引力,我在这里时间长些,混了点分,如果你要发高分问题,留句话,借你300分提问好了,ok?[:)]

测试数据是一个38M的SQL脚本,都是insert语句,是某次测试生成SQL语句代码的产物。
 
每段代码测试4轮,每次循环50次,得到上面的结果,最后一行是每轮的平均值。
ss基本在 59x ms左右
kill32基本在 81x ms左右
ss1基本在 64x ms左右
ss2基本在 57x ms左右

经过同一数据多次测试,除了在不同环境下总体数值略有变化,彼此间的差距基本也在这个值范围内,加上昨天的测试,所以,我认为kill32并不够像kinneng所说,一定比pascal代码快。

在多次测试结果中,得到的都是相近的结果,并没有很跳跃的测试结果,我想,这个测试数据应该是可信的。
 
这是另外一个4M左右的脚本的200次测试结果:
ss kill32
60 60 70 70 111 110 100 110
80 70 70 70 110 110 100 111
60 60 71 70 100 110 110 100
80 71 70 70 110 111 100 110
70 80 80 70 100 110 120 110
81 70 70 70 110 110 111 110
70 60 80 70 100 110 110 110
70 80 60 70 111 111 100 100
70 70 80 60 120 120 110 100
70 80 70 70 100 100 101 110
70 70 80 71 110 110 100 100
70 80 70 70 101 100 110 110
70 71 70 80 100 100 110 111
70 70 60 70 110 110 100 100
61 70 70 80 120 101 100 100
70 70 70 70 100 100 110 110
70 70 81 70 110 110 100 111
90 70 70 70 110 110 110 110
70 80 70 70 111 111 110 110
80 80 60 71 120 110 110 110
70 70 70 70 100 110 121 110
80 80 70 70 100 110 110 110
70 70 70 70 101 110 110 100
71 70 60 70 100 110 110 101
80 70 70 80 100 120 100 110
70 70 71 70 110 111 110 100
60 71 70 70 100 100 110 110
70 70 70 70 100 110 100 111
70 60 80 60 110 110 110 100
70 70 70 70 111 111 100 100
70 70 70 70 100 110 100 100
70 80 80 70 100 110 111 100
91 70 70 80 110 100 110 110
70 70 70 71 101 111 100 100
70 70 70 70 110 100 110 100
70 71 70 70 110 110 111 100
70 70 60 70 100 110 110 100
71 70 80 70 100 110 100 110
70 70 70 70 100 100 110 111
70 80 81 70 100 110 110 100
70 70 70 70 100 121 100 110
70 70 80 70 110 110 110 100
70 70 70 71 110 100 101 101
70 70 70 70 100 110 100 130
60 70 70 70 101 131 100 110
80 60 70 80 110 100 110 100
71 70 70 70 110 100 101 110
70 70 70 70 100 100 110 100
70 60 71 70 111 100 100 110
70 71 70 70 110 100 100 111

71.32 70.7 71.1 70.68 105.78 108.18 106.14 106.16

ss1 ss2
80 90 80 70 60 70 70 60
80 70 70 90 60 70 70 70
70 80 81 80 81 60 60 60
80 81 80 81 60 71 60 60
80 80 80 80 70 70 70 70
90 70 80 80 60 70 70 70
90 80 80 80 70 60 70 71
71 80 80 80 70 70 70 70
80 80 80 80 60 71 60 70
80 90 80 80 80 70 70 60
90 80 80 70 70 70 60 70
91 80 80 90 61 70 70 70
80 80 80 80 70 70 60 60
70 90 90 80 60 70 70 60
80 80 80 80 70 70 70 70
80 80 91 90 60 80 80 60
90 81 70 81 70 70 61 70
80 80 80 80 60 60 70 70
80 70 80 80 80 70 70 70
70 110 70 80 70 70 70 60
80 80 80 70 70 60 60 61
80 80 80 90 70 60 70 70
80 80 80 80 70 81 80 70
80 80 80 80 60 70 70 60
81 70 80 80 70 70 70 60
80 90 80 91 71 70 70 61
80 70 80 70 70 70 70 70
80 80 80 80 70 60 60 70
80 70 81 80 70 70 70 70
80 81 70 71 80 70 60 70
80 80 80 70 70 70 61 70
80 80 80 80 70 70 60 70
80 80 80 80 60 70 70 70
70 70 90 80 70 70 70 70
80 80 90 80 60 70 60 60
80 80 80 70 70 70 61 80
90 80 80 70 60 71 60 70
81 80 81 80 70 60 60 60
80 81 90 81 70 60 70 60
70 80 70 80 61 80 60 71
80 80 90 80 60 80 90 70
80 80 81 80 70 61 60 60
90 81 80 80 60 60 80 80
70 70 80 80 70 70 60 70
80 80 70 90 61 70 71 70
80 80 80 80 70 60 70 70
80 80 80 90 70 70 70 70
80 80 70 70 70 70 70 60
70 80 80 80 70 70 70 70
80 80 80 80 60 80 71 70

79.88 79.9 79.9 79.7 67.3 68.9 67.5 67.08
 
没必要if integer(s)=0 ...
直接 if s = '' ...
编译器会处理成integer(s)=0的:目标代码相当于:if pointer(s) = nil
length(s)编译器会首先查看s是否为空串
test eax,eax //测试S是否为空
jz +$03
mov eax, [eax - $04] //相当于pinteger(integer(s)-4)^
ret
length(s)是个函数,有调用与返回过程,加上会检查是否为空串,所以比你直接pinteger(integer(s)-4)^要慢,但从安全角度考虑,最好用length(s)呵


大家交流交流,很有意思呵,没别的意思。
 
这是另外一个19M左右的脚本的200次测试结果:
ss kill32
300 310 311 310 421 420 431
310 310 301 300 430 440 421
320 310 321 300 410 430 421
311 311 301 310 420 410 431
321 321 311 310 420 420 430
301 301 310 311 420 431 420
301 311 300 301 410 421 430
321 321 300 301 421 421 410
300 300 310 311 431 411 450
310 300 380 311 431 431 421
310 320 430 310 421 431 421
310 310 401 320 411 421 431
340 320 311 300 421 431 421
310 310 311 310 431 421 431
301 301 310 320 421 430 411
311 301 320 310 420 420 421
311 311 310 321 430 440 431
311 311 310 301 430 420 431
310 321 310 301 420 420 420
300 300 300 311 420 421 430
300 300 311 301 431 421 410
300 310 301 300 431 431 430
310 310 301 310 441 421 420
320 330 311 310 421 421 421
311 300 311 310 431 411 431
301 301 310 300 431 431 431
311 321 300 310 411 421 421
311 311 310 311 431 421 421
321 311 310 301 420 420 421
310 321 300 311 430 430 421
300 310 310 311 420 430 421
310 310 311 311 420 420 410
300 300 321 310 430 420 420
300 310 301 300 420 421 430
320 320 311 300 421 411 410
311 301 311 320 421 421 430
301 311 320 310 441 431 420
321 311 310 310 421 431 441
311 301 300 311 421 421 421
301 311 320 301 411 411 421
310 300 300 301 421 421 421
310 300 310 321 411 431 421
320 320 311 301 410 420 421
310 300 311 310 420 410 421
300 320 311 300 420 430 421
320 310 311 310 420 420 420
311 300 311 310 410 430 430
311 301 320 310 430 431 420
311 311 300 310 421 421 430
311 311 310 321 421 431 440

309.86 309.46 314.66 308.22 422.54 423.6 424.18

ss1 ss2
431 331 330 330 340 290 290 291 291
431 331 340 330 330 300 300 290 290
431 350 330 340 331 291 300 300 290
421 320 320 331 341 291 291 290 290
421 320 331 331 341 291 291 290 290
421 340 331 341 331 291 291 300 290
430 330 331 331 331 300 290 291 301
420 330 341 331 331 290 290 301 301
420 340 331 341 321 290 300 301 311
420 320 331 331 341 290 290 281 291
430 331 331 341 320 290 290 290 290
420 341 331 341 320 311 301 290 290
421 331 330 320 330 301 291 290 300
431 341 320 320 330 291 301 300 290
431 341 330 340 330 301 301 300 290
421 331 340 330 330 300 300 301 311
421 321 320 340 320 290 290 291 291
421 341 320 340 340 300 290 291 301
431 331 350 330 320 290 300 301 291
420 340 320 340 331 311 290 290 300
420 330 330 341 341 301 281 300 290
420 330 341 331 321 291 301 300 290
430 330 331 341 331 291 301 290 290
430 340 331 331 351 290 301 320 290
420 320 341 321 331 300 301 301 291
431 340 321 341 331 300 290 301 301
421 330 321 351 351 290 290 291 291
441 320 341 321 320 300 300 301 290
421 341 331 341 330 291 280 300 300
421 341 330 330 340 291 290 290 290
431 331 340 330 330 301 291 290 300
431 331 330 340 330 291 301 300 290
421 331 330 330 330 290 301 290 290
420 321 340 330 330 290 291 301 301
430 331 330 330 320 290 310 301 281
410 331 330 330 340 300 290 291 291
430 330 350 330 331 290 300 301 300
420 330 340 341 331 301 290 300 290
430 330 331 341 341 301 290 290 300
421 330 331 331 351 291 291 290 300
421 350 331 331 331 301 291 290 290
441 330 341 341 321 290 291 300 320
431 330 331 331 321 290 291 291 301
421 330 331 331 341 300 290 291 291
421 330 341 331 330 290 300 301 291
421 341 331 331 320 300 290 291 301
420 321 321 330 340 291 290 280 300
430 331 330 330 330 291 300 290 300
420 341 330 340 330 301 291 290 290
420 331 320 320 330 291 301 300 300

424.76 332.28 331.7 333.54 331.68 294.88 294.24 295.02 294.98
 
//咱们跑题太远拉[:D]
//发点关于测试程序运行时间的代码
procedure msgBox(const info: string; const title: string = '提示');

//此组方法用于测试程序性能,开始后不需要关闭,查看结果对当前的记时没有影响
//仅可以一个线程使用
procedure btStartTiming; //开始记时
procedure btSuspend; //暂停,停止
procedure btRestore; //恢复
procedure btSearch; //查看性能测试结果

implementation

procedure msgBox(const info, title: string);
begin
application.MessageBox(PAnsiChar(info), PAnsiChar(title),
MB_OK or MB_ICONINFORMATION);
end;

var
osbtFrequency,
osbtPerformanceCount,
osbtSuspend: Int64;

procedure btStartTiming; //开始记时
begin
osbtPerformanceCount := 0;
osbtSuspend := 0;
if QueryPerformanceFrequency(osbtFrequency) then
QueryPerformanceCounter(osbtPerformanceCount);
end;

procedure btSuspend; //暂停,停止
begin
if osbtSuspend = 0 then
QueryPerformanceCounter(osbtSuspend);
end;

procedure btRestore; //恢复
var
tmpInt64: int64;
begin
if osbtSuspend = 0 then
EXIT;

tmpInt64 := osbtSuspend - osbtPerformanceCount;

QueryPerformanceCounter(osbtPerformanceCount);
osbtPerformanceCount := osbtPerformanceCount - tmpInt64;
osbtSuspend := 0;
end;

procedure btSearch; //查看性能测试结果
var
tmpInt64: int64;
begin
btSuspend;
if osbtFrequency > 0 then
begin
tmpInt64 := osbtSuspend - osbtPerformanceCount;
msgBox('累计毫时:' + IntToStr(tmpInt64 div osbtFrequency) +
'.' + IntToStr((tmpInt64 mod osbtFrequency) div (osbtFrequency div 1000))
+
'秒');
end
else
msgBox('平台不支持当前使用的性能测试方法!');
btRestore;
end;
 
[]这个操作符速度是很快的,可以放心使用,你用汇编也快不了
 
谢谢楼上各位讨论.已结贴,只可惜分太少了.
 
好,帮顶



--------签名档---------------------------

比肩国内顶尖源码下载站点 -> 源码我爱你

http://www.source520.com
http://www.source520.net

80G源码电子书免费免注册下载,大量精辟技术文档库随时更新
******************************************************************
附:为了站点持续发展,现有本站近年来收藏的大量大型商业源码低价出售,
详情请进入以下链接查看:
http://www.source520.com/building_delphi.htm

浏览商业代码请从如下URL进入查看实物:
1.商业源码库1: ftp://source520see3:browse@61.152.199.245/
2.商业源码库2: ftp://source520see2:browse@61.152.199.245/
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
582
import
I
I
回复
0
查看
763
import
I
I
回复
0
查看
881
import
I
后退
顶部