C#v.C ++性能 [英] C# v. C++ Performance

查看:91
本文介绍了C#v.C ++性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到C#的JIT编译器生成非常高效的
机器代码。但是,我发现在进行广泛的数值计算时,C#的速度比C ++的速度低四分之一。我在下面给出代码示例。

C#和C ++都是作为发布版本编译的,默认情况下是优化的(C ++除了默认的/ b $ b优化之外还设置了/ Ob1)。我怀疑相对较差的C#

性能是由于使用了托管内存,但

为相关的类和方法添加''unsafe''使得

很少或没有区别。


我很欣赏有关如何使C#

性能接近C ++或者确认的建议

对于下面的代码示例,C#基本上比(非托管)C ++慢几倍。


C ++代码:


double total = 0.0;


for(int rep = 0; rep< 5; rep ++)

{

总计= = 1000.0;


for(long i = 0; i< 100000000; i ++)

{

总计+ = i / 999999.0;

双碟=总*总+ i;

双根=(总+碟)/

(200000.0 *(i + 1));

总计 - = root;

}

}


C#代码:


double total = 0.0;


for(int rep = 0; rep&l t; 5; rep ++)

{

总计/ = 1000.0;


for(long i = 0;我<

100000000; i ++)

{

总计+ =

i / 999999.0;

双碟=

总计*总计+ i;

双根=

(总计+光盘)/(200000.0 *(i + 1));

total - = root;

}

}

解决方案

本机代码中的长32位(C / C ++)但在托管代码中是64位,更改

.... for(long i = 0; i<> 100000000; i ++)in C#code into for(int

i = ...


Willy。

" Nigel"< ni *** @ nigelwilson.evesham.net .remove_this>写在留言中

news:0a **************************** @ phx.gbl。 ..

我读到C#的JIT编译器生成了非常高效的机器代码。但是,我发现在进行广泛的数值计算时C#小于第四,C ++的速度。我给出了下面的代码示例。将C#和C ++编译为默认的发布版本
优化(C ++除了默认优化之外还设置了/ Ob1)。我怀疑相对较差的C#
性能是由于使用了托管内存,但是对相关的类和方法添加不安全会使得很少或没有区别。
性能接近C ++的建议,或者对下面的代码示例的确认,C#从根本上说要慢几倍C ++代码:

对于(int rep = 0; rep< 5; rep ++)
{
总计/ = 1000.0;

for(long i = 0; i< 100000000; i ++)
{
总数+ = i / 999999.0;
双碟=总*总+ i;
双根=(总+碟)/
(200000.0 *(i + 1));
总计 - = root;
}

C#代码:

for double total = 0.0;

for(int rep = 0; rep< 5; rep ++)
{
总计/ = 1000.0;

for(long i = 0; i<
100000000; i ++)
{
总计+ =
i / 999999.0;
双碟=
总*总+ i;
双根=
(总+碟)/(200000.0 *(i + 1));
总计 - = root;
}
}



我不能提供更多的评论那一刻,但根据我的经验

数值计算恰恰是C#应该与C ++相同的区域。我已经用C#获得了非常好的结果,用于强烈的数值计算。如果,出于某种原因,你最终发现C#不会这样做(我会感到惊讶),你可以随时把最好的表现
$ b使用C或C ++中的$ b敏感代码(即使在非托管DLL中)并从C#中调用它。

我之前已经完成了非常好的结果(仅因为某些代码是

已经在C)中。使用PInvoke的表现非常好。

HTH


" Nigel" < NI *** @ nigelwilson.evesham.net.remove_this>在消息中写道

news:0a **************************** @ phx.gbl ... < blockquote class =post_quotes>我读到C#的JIT编译器生成非常高效的机器代码。但是,我发现在进行广泛的数值计算时,C#小于C ++速度的四分之一。我在下面给出代码示例。将C#和C ++编译为发布版本,默认优化(C ++除了默认优化之外还设置了/ Ob1)。我怀疑相对较差的C#
性能是由于使用了托管内存,但是对相关的类和方法添加不安全会使得很少或没有区别。
性能接近C ++的建议,或者对下面的代码示例的确认,C#从根本上说要慢几倍C ++代码:

对于(int rep = 0; rep< 5; rep ++)
{
总计/ = 1000.0;

for(long i = 0; i< 100000000; i ++)
{
总数+ = i / 999999.0;
双碟=总*总+ i;
双根=(总+碟)/
(200000.0 *(i + 1));
总计 - = root;
}

C#代码:

for double total = 0.0;

for(int rep = 0; rep< 5; rep ++)
{
总计/ = 1000.0;

for(long i = 0; i<
100000000; i ++)
{
总计+ =
i / 999999.0;
双碟=
总*总+ i;
双根=
(总+碟)/(200000.0 *(i + 1));
总计 - = root;
}
}



Nigel< ni *** @ nigelwilson.evesham。 net.remove_this>写道:

我读到C#的JIT编译器生成非常高效的机器代码。


C#没有JIT编译器。 .NET有一个JIT编译器。你需要非常明确边界的位置。

然而,我发现在进行广泛的数值计算时C#小于a
第四个C ++的速度。我在下面给出代码示例。将C#和C ++编译为发布版本,默认优化(C ++除了默认优化之外还设置了/ Ob1)。我怀疑相对较差的C#
性能是由于使用了托管内存,但是对相关的类和方法添加不安全会使得很少或没有区别。
性能接近C ++的建议,或者对下面的代码示例的确认,C#从根本上说要慢几倍比(非托管)C ++。




C#本身是一种语言,而不是一种实现。但是,假设

实际上不是问题......从根本上说这是一个非常奇怪的词语

在这里使用 - 毫无疑问会产生某些基准测试

其中C ++最终比C#慢 - 两种语言本身怎么样? />
每个都是从根本上的比其他更慢?


在某些情况下,C ++会比C#更快,而副本
$ b $反之亦然。


现在,让我们来看看你的情况。以下是我的笔记本电脑的原始数字 - 不是理想的测试方案,但不是一个糟糕的起点:


首次运行:

C ++:27s

C#:70s


这已经不到你引用的四倍 - 实际上,

它甚至不是慢三倍。不过,让我们看看我们能做些什么...


这里看起来有很多从长到两的铸造。更改

C#代码:


for(int rep = 0; rep< 5; rep ++)

{

总计= = 1000.0;


for(double i = 0; i< 100000000d; i + = 1.0d)

{

总计+ = i / 999999.0;

双碟=总*总+ i;

双根=(总+碟)/( 200000.0 *(i + 1.0d));

总计 - = root;

}

}


C#的执行时间缩短到18秒! (结果

看起来是一样的,我不明白为什么它不是一个完美的

有效优化来执行 - 唯一可能的损失精确度

将转换(i + 1)转换为双倍会产生不同的

结果,将1.0加到i的双倍值。我已经验证

不会出现在0-100000000范围内的任何地方;在实际代码中你可能想要检查它是否有问题。


以类似的方式更改C ++代码似乎没有帮助它。


因此,根据以上所述,你会承认 ; C#是
从根本上明显快于(非托管)C ++,或者你是否会b / b
承认单个基准测试不一定是一个好的指示

整个平台?


-

Jon Skeet - < sk *** @ pobox.com>
< a rel =nofollowhref =http://www.pobox.com/~sk eettarget =_ blank> http://www.pobox.com/~skeet

如果回复小组,请不要给我发邮件


I read that C#''s JIT compiler produces very efficient
machine code. However, I''ve found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding ''unsafe'' to relevant classes and methods makes
little or no difference.

I''d appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.

C++ Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i < 100000000; i++)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/
(200000.0*(i + 1));
total -= root;
}
}

C# Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i <
100000000; i++)
{
total +=
i/999999.0;
double disc =
total*total + i;
double root =
(total + disc)/(200000.0*(i + 1));
total -= root;
}
}

解决方案

Longs 32bit in native code (C/C++) but are 64 bit in managed code, change
.... for (long i = 0; i < > 100000000; i++) in you C# code into for (int
i=...

Willy.
"Nigel" <ni***@nigelwilson.evesham.net.remove_this> wrote in message
news:0a****************************@phx.gbl...

I read that C#''s JIT compiler produces very efficient
machine code. However, I''ve found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding ''unsafe'' to relevant classes and methods makes
little or no difference.

I''d appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.

C++ Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i < 100000000; i++)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/
(200000.0*(i + 1));
total -= root;
}
}

C# Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i <
100000000; i++)
{
total +=
i/999999.0;
double disc =
total*total + i;
double root =
(total + disc)/(200000.0*(i + 1));
total -= root;
}
}



I can''t offer much more than a comment at the moment, but in my experience
numerical calculations are precisely the area where C# should be on equal
ground with C++. I''ve had very good results with C# for intense numerical
computations. If, for some reason, you end up finding out the C# won''t do
the job (I''d be surprised), you could always put the most performance
senstive code in C or C++ (even in an unmanaged DLL) and call it from C#.
I''ve done that before with very good results (only because some code was
already in C). The performance using PInvoke was really good.
HTH

"Nigel" <ni***@nigelwilson.evesham.net.remove_this> wrote in message
news:0a****************************@phx.gbl...

I read that C#''s JIT compiler produces very efficient
machine code. However, I''ve found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding ''unsafe'' to relevant classes and methods makes
little or no difference.

I''d appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.

C++ Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i < 100000000; i++)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/
(200000.0*(i + 1));
total -= root;
}
}

C# Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i <
100000000; i++)
{
total +=
i/999999.0;
double disc =
total*total + i;
double root =
(total + disc)/(200000.0*(i + 1));
total -= root;
}
}



Nigel <ni***@nigelwilson.evesham.net.remove_this> wrote:

I read that C#''s JIT compiler produces very efficient
machine code.
C# doesn''t have a JIT compiler. .NET has a JIT compiler. You need to be
very clear on where the boundaries are.
However, I''ve found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding ''unsafe'' to relevant classes and methods makes
little or no difference.

I''d appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.



C# itself is a language, not an implementation. However, assuming that
weren''t actually a problem... "fundamentally" is a very strange word to
use here - there are certain benchmarks that could no doubt be produced
where C++ ends up slower than C# - how can two languages themselves
each be "fundamentally" slower than the other?

There are certain situations where C++ will be faster than C#, and vice
versa.

Now, let''s look at your case in point. Here are the raw numbers from my
laptop - not the ideal testing scenario, but not a bad starting point:

First run:
C++: 27s
C#: 70s

Already this is less than the factor of four you were quoting - indeed,
it''s not even three times as slow. Still, let''s see what we can do...

There looks to be a lot of casting from long to double here. Changing
the C# code to:

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (double i = 0; i < 100000000d; i+=1.0d)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/(200000.0*(i + 1.0d));
total -= root;
}
}

the execution time for C# goes down to just 18 seconds! (The results
appear to be the same, and I can''t see why it wouldn''t be a perfectly
valid optimisation to perform - the only possible loss of precision
would be where converting (i+1) to a double would have a different
result to adding 1.0 to the double value of i. I''ve verified that
doesn''t occur anywhere in the range 0-100000000; in actual code you
might want to check whether or not it could be a problem.

Changing the C++ code in a similar way doesn''t appear to help it.

So, according to the above, would you acknowledge that "C# is
fundamentally significantly faster than (unmanaged) C++" or would you
acknowledge that single benchmarks aren''t necessarily a good indication
of an entire platform?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


这篇关于C#v.C ++性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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