可以看出,测试的结果(效率)是: PosN_PosEx > PosN_StrPos > PosN_Pos >> GetNSubStringPos 。
我本来期望的是 PosN_StrPos 最厉害,但结果不是。估计是 PosEx 优化得比较厉害。
附代码:
Unit1.pas:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, DBTables;
type
TPosNFunc = function (N: Integer; const SubString,AString: String): Integer;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure Tests(const funcs: array of TPosNFunc;
const funcnames: array of string; iStr: integer; loopcount: integer);
public
end;
var
Form1: TForm1;
implementation
uses
StrUtils;
{$R *.dfm}
function GetNSubStringPos(N: Integer; SubString,AString: String): Integer;
//返回第n个SubString在AString中出现的位置
//如果没找到,返回-1
var
FindCount: Integer;
Pos: Integer;
begin
Result := -1;
Pos := 0;
for FindCount := 1 to N do begin
Inc(Pos);
while MidStr(AString, Pos, Length(SubString)) <> SubString do begin
if Length(AString) < Length(SubString) + Pos then
Exit;//未找到
Inc(Pos);
end;
end;
Result := Pos;
end;
function PosN_Pos(N: Integer; SubString, AString: String): Integer;
var
p: integer;
nSub: integer;
nSrc: integer;
begin
nSub := Length( SubString );
nSrc := Length( AString );
result := -nSub;
while N>0 do
begin
p := Pos(SubString, AString);
if p=0 then
break;
Dec( N );
Inc( result, p+nSub );
AString := Copy( AString, p+nSub+1, nSrc-nSub-p-1 );
Dec( nSrc, nSub+p );
end;
if N>0 then
result := -1;
end;
function PosN_PosEx(N: Integer; SubString,AString: String): Integer;
var
p: integer;
nSub: integer;
begin
nSub := Length( SubString );
result := 0;
p := 0;
while N>0 do
begin
p := PosEx( SubString, AString, p+1 );
if p=0 then
break;
Dec( N );
result := p;
Inc( p, nSub );
end;
if N>0 then
result := -1;
end;
function PosN_StrPos(N: Integer; SubString, AString: String): Integer;
var
pSub, pSrc, p: Pchar;
nSub: integer;
begin
nSub := Length( SubString );
pSub := PChar(SubString);
pSrc := PChar(AString);
p := pSrc;
while (N>0) do
begin
p := StrPos( p, pSub );
if (p=nil) then
break;
Inc( p, nSub );
Dec( N );
end;
if (N=0) and (p<>nil) then
result := p - pSrc
else
result := 0;
end;
const
STR = 'function GetNSubStringPos(N: Integer; SubString,AString: String): Integer;';
SUBSTR = 'String';
TEST_COUNT = 5;
procedure TForm1.Tests( const funcs: array of TPosNFunc;
const funcnames: array of string;
iStr: integer;
loopcount: integer );
var
i, j, k: Integer;
tm: Longword;
func: TPosNFunc;
count: integer;
retv: array of integer;
results: array of Longword;
begin
count := Length(funcs);
assert( count=Length(funcnames) );
Memo1.Lines.Add( Format('substr index: %d; LOOP COUNT = %d',
[iStr, loopCount]) );
SetLength( retv, count );
SetLength( results, count );
for j:=0 to count-1 do
results[j] := 0;
for k:=1 to TEST_COUNT do
begin
for j:=0 to count-1 do
begin
func := funcs[j];
tm := GetTickCount;
for i:=1 to loopcount do
retv[j] := func( iStr, SUBSTR, str );
Inc( results[j], GetTickCount - tm );
end;
end;
for j:=0 to count-1 do
begin
Memo1.Lines.Add( Format( '%s: return %d; Timing: %n ms',
[funcnames[j], retv[j],
results[j]*1.0/TEST_COUNT ] ) );
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
for i:=1 to 4 do
begin
Memo1.Lines.Add( Format( '%d:', [i]) );
Tests( [@GetNSubStringPos], ['GetNSubStringPos'], i, 1000 );
Tests( [@PosN_Pos, @PosN_PosEx, @PosN_StrPos],
['PosN_Pos', 'PosN_PosEx', 'PosN_StrPos'],
i, 100000 );
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
Memo1.Lines.Add( Format( 'Search "%s" for "%s"', [STR, SUBSTR] ) );
end;
end.
Unit1.dfm:
object Form1: TForm1
Left = 243
Top = 164
Width = 578
Height = 516
AlphaBlendValue = 192
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poDefaultPosOnly
OnCreate = FormCreate
DesignSize = (
570
489)
PixelsPerInch = 96
TextHeight = 13
object Memo1: TMemo
Left = 3
Top = 32
Width = 565
Height = 457
Anchors = [akLeft, akTop, akRight, akBottom]
Lines.Strings = (
'Memo1')
ScrollBars = ssVertical
TabOrder = 0
end
object Button1: TButton
Left = 3
Top = 6
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
end
煤炭网版权与免责声明:
凡本网注明"来源:煤炭网www.coal.com.cn "的所有文字、图片和音视频稿件,版权均为"煤炭网www.coal.com.cn "独家所有,任何媒体、网站或个人在转载使用时必须注明"来源:煤炭网www.coal.com.cn ",违反者本网将依法追究责任。
本网转载并注明其他来源的稿件,是本着为读者传递更多信息的目的,并不意味着本网赞同其观点或证实其内容的真实性。其他媒体、网站或个人从本网转载使用时,必须保留本网注明的稿件来源,禁止擅自篡改稿件来源,并自负版权等法律责任。违反者本网也将依法追究责任。 如本网转载稿件涉及版权等问题,请作者在两周内尽快来电或来函联系。
网站技术运营:北京真石数字科技股份有限公司、喀什中煤远大供应链管理有限公司、喀什煤网数字科技有限公司
总部地址:北京市丰台区总部基地航丰路中航荣丰1层
京ICP备18023690号-1 京公网安备 11010602010109号
