德尔福:
procedure TForm1.Button1Click(Sender: TObject);
var I,Tick:Integer;
begin
Tick := GetTickCount();
for I := 0 to 1000000000 do
begin
end;
Button1.Caption := IntToStr(GetTickCount()-Tick)+' ms';
end;
C#:
private void button1_Click(object sender, EventArgs e)
{
int tick = System.Environment.TickCount;
for (int i = 0; i < 1000000000; ++i)
{
}
tick = System.Environment.TickCount - tick;
button1.Text = tick.ToString()+" ms";
}
德尔福提供大约515毫秒
C#给出大约3775毫秒
Cli*_*ord 29
Delphi被编译为本机代码,而C#被编译为CLR代码,然后在运行时进行翻译.那就是说C#确实使用了JIT编译,所以你可能期望时间更相似,但它不是给定的.
如果你可以描述你运行它的硬件(CPU,时钟速率)将是有用的.
我无法访问Delphi重复您的实验,但使用本机C++与C#和以下代码:
VC++ 2008
#include <iostream>
#include <windows.h>
int main(void)
{
int tick = GetTickCount() ;
for (int i = 0; i < 1000000000; ++i)
{
}
tick = GetTickCount() - tick;
std::cout << tick << " ms" << std::endl ;
}
Run Code Online (Sandbox Code Playgroud)
C#
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int tick = System.Environment.TickCount;
for (int i = 0; i < 1000000000; ++i)
{
}
tick = System.Environment.TickCount - tick;
Console.Write( tick.ToString() + " ms" ) ;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我最初得到:
C++ 2792ms
C# 2980ms
Run Code Online (Sandbox Code Playgroud)
然而,我然后在C#版本上执行了重建,<project>\bin\release并<project>\bin\debug分别直接从命令行运行可执行文件.这产生了:
C# (release): 720ms
C# (debug): 3105ms
Run Code Online (Sandbox Code Playgroud)
所以我认为这就是差异真正存在的地方,你是从IDE运行C#代码的调试版本.
如果您认为C++特别慢,我将其作为优化版本构建运行并获得:
C++ (Optimised): 0ms
Run Code Online (Sandbox Code Playgroud)
这并不奇怪,因为循环是空的,并且控制变量不在循环外使用,因此优化器完全删除它.为了避免我声明i为volatile具有以下结果:
C++ (volatile i): 2932ms
Run Code Online (Sandbox Code Playgroud)
我的猜测是C#实现也删除了循环,而720ms来自其他东西; 这可以解释第一次测试中时间的大部分差异.
Delphi在做什么我无法分辨,你可能会看看生成的汇编代码.
所有上述测试均采用AMD Athlon双核5000B 2.60GHz,适用于Windows 7 32位.
如果这是一个基准测试,那么这是一个非常糟糕的基准测试,因为在这两种情况下都可以优化循环,所以你必须查看生成的机器代码才能看到正在发生的事情.如果您使用C#的发布模式,请使用以下代码
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000000000; ++i){ }
sw.Stop();
Console.WriteLine(sw.Elapsed);
Run Code Online (Sandbox Code Playgroud)
由JITter转换为:
push ebp
mov ebp,esp
push edi
push esi
call 67CDBBB0
mov edi,eax
xor eax,eax ; i = 0
inc eax ; ++i
cmp eax,3B9ACA00h ; i == 1000000000?
jl 0000000E ; false: jmp
mov ecx,edi
cmp dword ptr [ecx],ecx
call 67CDBC10
mov ecx,66DDAEDCh
call FFE8FBE0
mov esi,eax
mov ecx,edi
call 67CD75A8
mov ecx,eax
lea eax,[esi+4]
mov dword ptr [eax],ecx
mov dword ptr [eax+4],edx
call 66A94C90
mov ecx,eax
mov edx,esi
mov eax,dword ptr [ecx]
mov eax,dword ptr [eax+3Ch]
call dword ptr [eax+14h]
pop esi
pop edi
pop ebp
ret
Run Code Online (Sandbox Code Playgroud)
TickCount不是一个可靠的计时器; 你应该使用.Net的Stopwatch课程.(我不知道Delphi的等价物是什么).
另外,您是否正在运行发布版本?
你有一个调试器吗?
| 归档时间: |
|
| 查看次数: |
3809 次 |
| 最近记录: |