加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

string – Delphi:64位快速Pos

发布时间:2020-12-15 09:42:46 所属栏目:大数据 来源:网络整理
导读:是否有任何Pos()版本的代码在64位上比当前的32位快? 据我所知,Delphi中的32位版本(经过XE5测试)多年前采用了FastCode汇编程序版本,但对于64位版本,它使用的是PurePascal版本,速度大约慢5到10倍. 一些测试,长循环中的相同过程: 32位:65..90ms 64位:280..3
是否有任何Pos()版本的代码在64位上比当前的32位快?

据我所知,Delphi中的32位版本(经过XE5测试)多年前采用了FastCode汇编程序版本,但对于64位版本,它使用的是PurePascal版本,速度大约慢5到10倍.

一些测试,长循环中的相同过程:

32位:65..90ms

64位:280..300ms

解决方法

使用 Fastcoders purepascal PosEx_Sha_Pas_2算法(修改为适合x64):

function PosEx_Sha_Pas_2(const SubStr,S: string; Offset: Integer = 1): Integer;
Type
  PInteger =^Integer;
var
  len,lenSub: Integer;
  ch: char;
  p,pSub,pStart,pStop: pchar;
label
  Loop0,Loop4,TestT,Test0,Test1,Test2,Test3,Test4,AfterTestT,AfterTest0,Ret,Exit;
begin;
  pSub := pointer(SubStr);
  p := pointer(S);

  if (p = nil) or (pSub = nil) or (Offset < 1) then
  begin;
    Result := 0;
    goto Exit;
  end;

  lenSub := PLongInt(PByte(pSub) - 4)^ - 1; // <- Modified
  len := PLongInt(PByte(p) - 4)^; // <- Modified
  if (len < lenSub + Offset) or (lenSub < 0) then
  begin;
    Result := 0;
    goto Exit;
  end;

  pStop := p + len;
  p := p + lenSub;
  pSub := pSub + lenSub;
  pStart := p;
  p := p + Offset + 3;

  ch := pSub[0];
  lenSub := -lenSub;
  if p < pStop then
    goto Loop4;
  p := p - 4;
  goto Loop0;

Loop4:
  if ch = p[-4] then
    goto Test4;
  if ch = p[-3] then
    goto Test3;
  if ch = p[-2] then
    goto Test2;
  if ch = p[-1] then
    goto Test1;
Loop0:
  if ch = p[0] then
    goto Test0;
AfterTest0:
  if ch = p[1] then
    goto TestT;
AfterTestT:
  p := p + 6;
  if p < pStop then
    goto Loop4;
  p := p - 4;
  if p < pStop then
    goto Loop0;
  Result := 0;
  goto Exit;

Test3:
  p := p - 2;
Test1:
  p := p - 2;
TestT:
  len := lenSub;
  if lenSub <> 0 then
    repeat
      ;
      if (pSub[len] <> p[len + 1]) or (pSub[len + 1] <> p[len + 2]) then
        goto AfterTestT;
      len := len + 2;
    until len >= 0;
  p := p + 2;
  if p <= pStop then
    goto Ret;
  Result := 0;
  goto Exit;

Test4:
  p := p - 2;
Test2:
  p := p - 2;
Test0:
  len := lenSub;
  if lenSub <> 0 then
    repeat
      ;
      if (pSub[len] <> p[len]) or (pSub[len + 1] <> p[len + 1]) then
        goto AfterTest0;
      len := len + 2;
    until len >= 0;
  Inc(p);
Ret:
  Result := p - pStart;
Exit:
end;

结果使用David的测试用例(x64版本):

System.Pos       18427
wcsstr            8122
PosEx_Sha_Pas_2   2282

对于x32版本,结果如??下:

System.Pos        2171
wcsstr            9634
PosEx_Sha_Pas_2   1868

结论:

在x32位模式下,PosEx_Sha_Pas_2在x64位模式下几乎和Pos一样快.
此外,似乎PosEx_Sha_Pas_2在x32位模式下比Pos快.

这里的所有测试都是使用XE4版本.

Improve purepascal System.Pos()仍在东京开放10.2.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读