不使用引用计数交换字符串

use*_*191 6 delphi string quicksort

在 QuickSort 中,很多时间都花在了 swap 上temp:=var[i]; var[i]:=var[j]; var[j]:=temp。当 vars 是整数时,我为大型随机数组计时 140 毫秒。当变量为字符串时,时间为 750 毫秒。在我看来,大部分差异是由于需要更新所有三个分配中的引用计数造成的。但这有必要吗?毕竟,在这三个赋值之前和之后,var[i] 和 var[j] 的引用计数是相同的。下面的代码会破坏东西吗?(不是说它解决了速度问题,而是出于兴趣):

    // P : Pstring;
    move(values[i],P,sizeOf(Pstring));
    move(values[j],values[i],sizeOf(Pstring));
    move(P,values[i],sizeOf(Pstring));
Run Code Online (Sandbox Code Playgroud)

没有临时变量。只有指向字符串的两个指针被交换。如果这没问题,是否有 Delphi 函数来交换 2 个指针?

Dav*_*nan 6

您提出的是众所周知且有效的优化。与其调用Move函数,不如使用强制转换执行直接赋值,以避免生成引用计数代码。

var
  temp: Pointer;
.... 
temp := Pointer(var[i]);
Pointer(var[i]) := Pointer(var[j]);
Pointer(var[j]) := temp;
Run Code Online (Sandbox Code Playgroud)

为了使其工作,您需要确信在交换过程中不会引发异常。有效内存的简单分配不会导致异常,因此可以很容易地消除这种担忧。

  • 这正是我们在 mORMot 中交换字符串的方式。;) (2认同)