德尔福:快速波什64位 [英] Delphi: fast Pos with 64-bit

查看:193
本文介绍了德尔福:快速波什64位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有code对于POS()版本,这是快于64位比目前的32位?

Is there any code for a Pos() version that's as fast in 64-bit than the current 32-bit?

据我了解,32位版本的Delphi(经测试高达XE5)采用快速code和汇编的版本很多年前,但对于64位,它使用一个PurePascal版本,这是约5〜10倍慢。

To my understanding, the 32-bit version in Delphi (tested up to XE5) adopted the FastCode assembler versions many years ago, but for 64-bit it uses a PurePascal version, which is around 5 to 10 times slower.

某些测试,在相当长的环路相同的过程:

Some tests, same procedure in a long loop:

32位:65..90ms

32-bit: 65..90ms

64位:280..300ms

64-bit: 280..300ms

推荐答案

使用 快速codeRS purepascal PosEx_Sha_Pas_2 算法(修改,以适应64):

Using Fastcoders purepascal PosEx_Sha_Pas_2 algorithm (modified to fit 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;

和使用大卫的测试案例(64位版本)的结果是:

And the result using David's test case (x64 release):

System.Pos       18427
wcsstr            8122
PosEx_Sha_Pas_2   2282

对于X32版本的结果是:

For the x32 release the results are:

System.Pos        2171
wcsstr            9634
PosEx_Sha_Pas_2   1868


结论:

PosEx_Sha_Pas_2 几乎是一样快的64位模式为波什在X32位模式。 此外,它似乎 PosEx_Sha_Pas_2 波什在X32位模式快。

PosEx_Sha_Pas_2 is almost as fast in x64 bit mode as Pos in x32 bit mode. Additionally it seems as PosEx_Sha_Pas_2 is faster than Pos in x32 bit mode.

在这里所有的测试与XE4版本。

All tests here is with the XE4 version.

为purepascal QC111103低效循环在POS()仍然打开XE8。

QC111103 Inefficient loop in Pos() for purepascal still open in XE8.

这篇关于德尔福:快速波什64位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆