不测不知道,一测吓一跳!
JAVA字符串性能比DELPHI字符串性能还好?
循环次数 Java 1.2 Java 1.2 Java 1.2 gcc 2.95
String StringBuffer StringBuffer STL-string
不分配内存 预先分配内存
外层1000000内层1 6190 480 450 1270
外层100000内层10 8230 310 300 2180
外层50000内层20 10620 310 290 1830
外层20000内层50 14780 310 290 1300
外层10000内层100 22500 310 290 1100
外层1000内层1000 性能极差 330 290 1120
外层100内层10000 360 360 1710
外层10内层100000 540 440 1220
外层1内层1000000 1570 900 910 循环次数 Delphi 6 BCB 6 BCB 6 SQL SERVER 2000
String STL-string AnsiString (10万数据)
外层1000000内层1 490 810 1310
外层100000内层10 390 580 2010 2300(内层1)
外层50000内层20 380 580 1900 1650(内层2)
外层20000内层50 380 560 1560 1540(内层5)
外层10000内层100 380 560 1450 1200(内层10)
外层1000内层1000 380 560 1240 1240(内层100)
外层100内层10000 440 600 1300 1250(内层1000)
外层10内层100000 420 640 1270 (最大8000字符)
外层1内层1000000 420 870 7400 代码:(JAVA,其他的类似。)
int a=Integer.parseInt(args[0]);
int b=1000000 / a
System.out.println("start...");
long t1=System.currentTimeMillis();
/*
for (int j=0; j<a; j++)
{
String s="";
for (int i=0; i<b; i++)
s += "aabbzzz";
}
*/
StringBuffer s = new StringBuffer(b*2);
for (int j=0; j<a; j++)
{
s.setLength(0);
for (int i=0; i<b; i++)
s.append("aabbzzz");
}
long t2=System.currentTimeMillis();
System.out.println( t2-t1);JAVA-String的性能级差,但StringBuffer的性能出人意料的好。
DELPHI性能仅仅次于StringBuffer,同时速度一直都很稳定。BCB下的STL-string性能也比较好。
JAVA字符串性能比DELPHI字符串性能还好?
循环次数 Java 1.2 Java 1.2 Java 1.2 gcc 2.95
String StringBuffer StringBuffer STL-string
不分配内存 预先分配内存
外层1000000内层1 6190 480 450 1270
外层100000内层10 8230 310 300 2180
外层50000内层20 10620 310 290 1830
外层20000内层50 14780 310 290 1300
外层10000内层100 22500 310 290 1100
外层1000内层1000 性能极差 330 290 1120
外层100内层10000 360 360 1710
外层10内层100000 540 440 1220
外层1内层1000000 1570 900 910 循环次数 Delphi 6 BCB 6 BCB 6 SQL SERVER 2000
String STL-string AnsiString (10万数据)
外层1000000内层1 490 810 1310
外层100000内层10 390 580 2010 2300(内层1)
外层50000内层20 380 580 1900 1650(内层2)
外层20000内层50 380 560 1560 1540(内层5)
外层10000内层100 380 560 1450 1200(内层10)
外层1000内层1000 380 560 1240 1240(内层100)
外层100内层10000 440 600 1300 1250(内层1000)
外层10内层100000 420 640 1270 (最大8000字符)
外层1内层1000000 420 870 7400 代码:(JAVA,其他的类似。)
int a=Integer.parseInt(args[0]);
int b=1000000 / a
System.out.println("start...");
long t1=System.currentTimeMillis();
/*
for (int j=0; j<a; j++)
{
String s="";
for (int i=0; i<b; i++)
s += "aabbzzz";
}
*/
StringBuffer s = new StringBuffer(b*2);
for (int j=0; j<a; j++)
{
s.setLength(0);
for (int i=0; i<b; i++)
s.append("aabbzzz");
}
long t2=System.currentTimeMillis();
System.out.println( t2-t1);JAVA-String的性能级差,但StringBuffer的性能出人意料的好。
DELPHI性能仅仅次于StringBuffer,同时速度一直都很稳定。BCB下的STL-string性能也比较好。
解决方案 »
- 帮帮忙!怎样自动点击网页上checkbox我用的delphi7 webbrowser控件
- 散尽最后一分,祝各位中秋节快乐!
- 有用过dxBarManager的达人吗?怎样将一个按钮关联上一个弹出菜单POPMENU
- 怎么动态的显示菜单,类似DLl一样,从Dll读取菜单内容
- 知道handle等信息,怎么拦截它的消息?
- << 征集 : 屏幕传输最快的代码 >> 大家一起讨论提高
- d7中rave如何做报表?
- 传言数据库开发栏中,有个阿拉伯神灯式人物咒语是(PROGAME,你在哪里,我们相念你............不知Delphi中是否也有如此人物??)不知Delphi中是否也有如此人物??
- 用Ado连Access库,怎么动态建立查询并保存在Access库中.
- 十万火急,请求帮助
- 在主模块中怎么调用模块
- DBGRID 问题
单位:ms
对于 String 操作符"+"的处理, 只有 ANSI C++ 处理还算可以。VB 的字符串性能也不好。
uses Windows,Classes;
type TStringBuilder=class
private
m_Capacity:Integer;
m_Memory:String;
procedure Allocate(dwSize:DWORD);
procedure AllocateNCopy(const Value:String;Capacity:Integer);
function FGetLength:Integer;
function FGetChar(Index:Integer):Char;
procedure FSetChar(Index:Integer;c:Char);
procedure Enlarge(bytes:dword);
public
property Chars[Index:Integer]:Char read FGetChar write FSetChar;default;
property Length:Integer read FGetLength;
property ToString:String read m_Memory;
constructor Create(Capacity:Integer);overload;
constructor Create(const Value:String;Capacity:Integer);overload;
constructor Create(const Value:String);overload;
constructor Create();overload;
procedure Append(const Value:String);end;
implementation
//overloaded constructor
constructor TStringBuilder.Create(Capacity:Integer);
begin
Allocate(Capacity);
end;
constructor TStringBuilder.Create(const Value:String;Capacity:Integer);
begin
AllocateNCopy(Value,Capacity);
// mov ecx, TStringBuilder.AllocateNCopy;
end;
constructor TStringBuilder.Create(const Value:String);
begin
AllocateNCopy(Value,System.Length(value)+4096);
end;
constructor TStringBuilder.Create();
begin
Allocate(4096);
end;
procedure TStringBuilder.AllocateNCopy(const Value:String;Capacity:Integer);
asm
push esi
push ebx
push eax//保护this指针
mov dword ptr [eax.m_Capacity],Capacity
mov esi,dword ptr [Value-4]//获取Value长度
cmp esi,ecx
jg @@next
mov esi,ecx//Capacity>Length(Value)
@@next:
add esi,4100//将Capacity和Length(value)的最大值加上4100字节(4K缓存和4Byte的长度)
push Value
//申请内存
push PAGE_READWRITE
push MEM_COMMIT
push esi
push 0
call VirtualAlloc
//复制字符串并修改相关内容
pop esi//Value
pop ebx//this
mov ecx,dword ptr [esi-4]//get length of value
mov dword ptr [eax],ecx//修改新字符串长度
add eax,4
mov dword ptr [ebx.m_Memory],eax
mov edi,eax
rep movsb
mov dword ptr [edi+2],0
pop ebx
pop esi
xor eax,eax
ret;
end;
procedure TStringBuilder.Allocate(dwSize:DWORD);
asm
mov [eax.m_Capacity],edx
push eax
add edx,4//增加一个保存长度的DWORD
push PAGE_READWRITE
push MEM_COMMIT
push edx
push 0
call VirtualAlloc
mov [eax],0//头一个DWORD保存String的长度
add eax,4
pop ecx
mov [ecx.m_Memory],eax
ret
end;
procedure TStringBuilder.Enlarge(bytes:dword);
asm
push esi
push eax
add edx,[eax.m_Capacity]//新内存长度
mov [eax.m_Capacity],edx//修改新长度
push self//
push PAGE_READWRITE
push MEM_COMMIT
push edx
push 0
call VirtualAlloc
pop ecx//self
mov esi,[ecx.m_Memory]
push esi
mov edi,eax
mov edx,[ecx.m_Memory]
push [edx-4]
pop [eax]
add eax,4
mov [ecx.m_Memory],eax//指向新地址
mov ecx,[edx-4]
mov edi,eax
rep movsb
pop esi
sub esi,4
push MEM_RELEASE
push 0
push esi
call VirtualFree//释放原来内存
pop eax
pop esi
ret
end;
procedure TStringBuilder.Append(const value:string);
asm
push esi
push edi
mov esi,[eax.m_Memory]//获取现在的字符串的长度
mov esi,[esi-4]
mov edi,[eax.m_Capacity]//获取已申请内存的大小
sub edi,esi
cmp edi,2048//若剩余空间长度不足2K则进行扩展
jg @WithouExtend
push edx
push esi
mov edx,[eax.m_Capacity]
add edx,4098//添加4K内存
push eax
call TStringBuilder.Enlarge//扩展
pop eax
pop esi
pop edx//value
@WithouExtend:
mov ecx,[edx-4]//获取value长度
mov edi,esi
add edi,ecx
push edi
mov edi,esi
add edi,[eax.m_Memory]//用于复制的新地址
mov esi,edx//原来地址
rep movsb
pop esi
mov edx,[eax.m_Memory]
mov [edx-4],esi
mov eax,[eax.m_Memory]
mov [eax-4],esi//修改长度
pop edi
pop esi
ret
end;
function TStringBuilder.FGetLength:Integer;
asm
mov eax,[eax.m_Memory]
mov eax,[eax-4]
end;
function TStringBuilder.FGetChar(Index:Integer):Char;
asm
mov ecx,[eax.m_Memory]
add ecx,edx
xor eax,eax
mov al,[ecx]
end;
procedure TStringBuilder.FSetChar(Index:Integer;c:Char);
asm
mov eax,[eax.m_Memory]
add eax,edx
mov [eax],cl
end;
end.
用汇编写……高手啊:)
你写好后,和DELPHI内建的string比较一下,然后可以得到相对数据。
Delphi写的,D7编译,测试我前面写的 TStringBuilder,速度最快的时候100外层循环达到耗时16微妙,所有代码统一采用timeGetTime计时H:\>for %x in (1,10,100,1000,10000,100000) do @dstrtest stringbuilder %x
StringBuilder外层1内层1000000耗时间60微秒
StringBuilder外层10内层100000耗时间29微秒
StringBuilder外层100内层10000耗时间27微秒
StringBuilder外层1000内层1000耗时间26微秒
StringBuilder外层10000内层100耗时间27微秒
StringBuilder外层100000内层10耗时间33微秒
我的电脑上Delphi里字符串的测试:
H:\>for %x in (1,10,100,1000,10000,100000) do @dstrtest string %x
String外层1内层1000000耗时间145微秒
String外层10内层100000耗时间146微秒
String外层100内层10000耗时间148微秒
String外层1000内层1000耗时间142微秒
String外层10000内层100耗时间140微秒
String外层100000内层10耗时间145微秒
C#代码,使用 .net framework 1.1编译
H:\>for %x in (1,10,100,1000,10000,100000) do @cstest stringbuilder %x
StringBuilder外层1内层1000000耗时间166微秒
StringBuilder外层10内层100000耗时间98微秒
StringBuilder外层100内层10000耗时间79微秒
StringBuilder外层1000内层1000耗时间72微秒
StringBuilder外层10000内层100耗时间78微秒
StringBuilder外层100000内层10耗时间77微秒.net framework自带编译器加优化编译:
H:\>for %x in (1,10,100,1000,10000,100000) do @cstest stringbuilder %x
StringBuilder外层1内层1000000耗时间137微秒
StringBuilder外层10内层100000耗时间85微秒
StringBuilder外层100内层10000耗时间80微秒
StringBuilder外层1000内层1000耗时间77微秒
StringBuilder外层10000内层100耗时间79微秒
StringBuilder外层100000内层10耗时间78微秒
Mono不带优化编译同样代码(不支持中文额):
StringBuildería2?1?ú2?1000000o?ê±??146?¢??
StringBuildería2?10?ú2?100000o?ê±??87?¢??
StringBuildería2?100?ú2?10000o?ê±??75?¢??
StringBuildería2?1000?ú2?1000o?ê±??73?¢??
StringBuildería2?10000?ú2?100o?ê±??74?¢??
StringBuildería2?100000?ú2?10o?ê±??80?¢??与上面同样的EXE,不过用Mono的CLR而不是MS的CLR执行:
H:\>for %x in (1,10,100,1000,10000,100000) do @mono cstest.exe stringbuilder %x
StringBuilder????1????1000000???±??301????
StringBuilder????10????100000???±??110????
StringBuilder????100????10000???±??77????
StringBuilder????1000????1000???±??78????
StringBuilder????10000????100???±??77????
StringBuilder????100000????10???±??82????使用MONO来执行MS编译器编译(已优化)的测试程序:
H:\>for %x in (1,10,100,1000,10000,100000) do @mono cstest.exe stringbuilder %x
StringBuilder外层1内层1000000耗时间292微秒
StringBuilder外层10内层100000耗时间108微秒
StringBuilder外层100内层10000耗时间78微秒
StringBuilder外层1000内层1000耗时间77微秒
StringBuilder外层10000内层100耗时间76微秒
StringBuilder外层100000内层10耗时间79微秒使用MONO来执行MS编译器编译(未优化)的测试程序:
H:\>for %x in (1,10,100,1000,10000,100000) do @mono cstest.exe stringbuilder %x
StringBuilder外层1内层1000000耗时间289微秒
StringBuilder外层10内层100000耗时间110微秒
StringBuilder外层100内层10000耗时间77微秒
StringBuilder外层1000内层1000耗时间75微秒
StringBuilder外层10000内层100耗时间78微秒
StringBuilder外层100000内层10耗时间78微秒
.net版本的也写了string的测试,但是不敢贴上来,执行了大约10分钟第一个结果还没出来 -_-! 寒~~
using System.Text;
using System.Runtime.InteropServices;
namespace CS_Test
{
public class CS_Test
{
public static void Usage()
{
Console.WriteLine("cstest stringbuilder|string times");
}
[DllImport("winmm.dll")]
extern static int timeGetTime();
public static void Main()
{
string[] args=Environment.GetCommandLineArgs();
if(args.Length!=3)
{
Usage();
return;
}
int times=int.Parse(args[2]);
if("stringbuilder"==args[1])
test_stringBuilder(times);
else
if("string"==args[1])
test_string(times);
else
Usage();
}
public static void test_stringBuilder(int times)
{
StringBuilder sb=new StringBuilder(40960);
int b=1000000/times;
int t1=timeGetTime();
for(int j=0;j<times;j++)
{
sb.Length=0;
for(int i=0;i<b;i++)
{
sb.Append("aabbzzz");
}
}
int t2=timeGetTime();
Console.WriteLine("StringBuilder外层{0}内层{1}耗时间{2}微秒",times,b,t2-t1);
}
public static void test_string(int times)
{
string s;
int b=1000000/times;
int t1=timeGetTime();
for(int j=0;j<times;j++)
{
s="";
for(int i=0;i<b;i++)
{
s+="aabbzzz";
}
}
int t2=timeGetTime();
Console.WriteLine("String外层{0}内层{1}耗时间{2}微秒",times,b,t2-t1);
}
}
}
________________________________________________________________________Delphi版本测试代码:
program DStrTest;{$APPTYPE CONSOLE}uses
SysUtils,lxcStringBuilder,mmsystem;
procedure Usage;
begin
Writeln('dstrtest stringbuilder|string times');
halt;
end;
procedure test_stringbuilder(times:Integer);
var s:TStringBuilder;
b,j,i:integer;
t1,t2:integer;
begin
b:=1000000 div times;
s:=TStringBuilder.Create(40960);
t1:=timeGetTime;
for j:=1 to times do
begin
s.Length :=0;
for i:=1 to b do
s.Append('aabbzzz');
end;
t2:=timeGetTime;
Writeln(Format('StringBuilder外层%d内层%d耗时间%d微秒',[times,b,t2-t1]));
// s.Free ;
end;
procedure test_string(times:integer);
var s:AnsiString;
b,j,i:integer;
t1,t2:integer;
begin
b:=1000000 div times;
Writeln('staring...');
t1:=timeGetTime;
for j:=1 to times do
begin
s:='';
for i:=1 to b do
s:=s+'aabbzzz';
end;
t2:=timeGetTime;
Writeln(Format('String外层%d内层%d耗时间%d微秒',[times,b,t2-t1]));
end;
var times:integer;
begin
if ParamCount<>2 then
Usage;
times:=StrToInt(ParamStr(2));
if(ParamStr(1)='stringbuilder')then
test_stringbuilder(times)
else
if(ParamStr(1)='string')then
test_string(times)
else
usage;
{ TODO -oUser -cConsole Main : Insert code here }
end.其他修改:TStringBuilder增加一个FSetLength的私有方法,用于Length属性的write里: procedure TStringBuilder.FSetLength(value:Integer);
asm
mov eax,[eax.m_Memory]
mov [eax-4],edx
end;
你也喜欢用AMD的呀,我也喜欢!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~俺的:Althlon 2500+, KT600 512MB DDR 400×1, Win XP Pro
综合考虑没选NForce2,因为硬盘是SATA的
寒一个
再次佩服!