缺乏C#中的for循环优化 [英] Lacking for-loop optimization in C#

查看:492
本文介绍了缺乏C#中的for循环优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在查看

编译器使用ms .net 2003生成的IL操作码时偶然发现了一个优化(或缺少一个,具体而言)。我正在快速测试
$ b使用Bitmap.LockBits和不安全指针进行$ b像素操作迭代

一个图像的像素。内循环看起来像这样:


for(int x = 0; x< _buffer.Width * _buffer.Height; x ++)

{

//在这里进行操作..

}


我注意到for循环执行得非常慢,ildasm显示

表示x< _buffer.Width * _buffer.Height"在每次迭代时计算,

导致两个虚拟调用和一个mul。使用/ optimize没有改善这个问题,所以解决方法是在for循环之外计算

_buffer.Width * _buffer.Height。我在

的印象中,编译器自动执行吊装,我在这里错过了什么?b $ b这里有什么东西?

I stumbled over an optimization (or lack of one, to be specific) when viewing
IL opcodes generated by the compiler using ms .net 2003. I was testing fast
pixel manipulation using Bitmap.LockBits and unsafe pointers to iterate over
an image''s pixels. The inner-loop looked like this:

for (int x = 0; x < _buffer.Width*_buffer.Height; x++)
{
// do manipulations here..
}

I noticed how the for-loop performed extremely slow, and ildasm revealed
that the "x < _buffer.Width*_buffer.Height" was computed at each iteration,
resulting in two virtual calls and one mul. The use of /optimize did not
improve the matter, so the solution was to calculate
_buffer.Width*_buffer.Height outside of the for-loop. I was under the
impression that the compiler performed hoisting automatically, am I missing
something here?

推荐答案

如果编译器不能保证在任何循环迭代过程中

_buffer.Width * _buffer.Height的值发生变化,那么它将会是
必须每次计算。这就是C / C ++ / C#for循环的本质。

在你想要的情况下使用for循环是很常见的。 (注意

VB永远不会重新计算结束条件)


David Anton
www.tangiblesoftwaresolutions.com

即时C#VB.NET到C#转换器的主页

和即时VB C#到VB.NET转换器


" MariusI"写道:
If the compiler can''t guarantee that the value of
_buffer.Width*_buffer.Height changes during any loop iteration, then it''ll
have to be calculated each time. That is the nature of a C/C++/C# for-loop.
It''s quite common to have for-loops where you want this to occur. (note that
VB never recalculates the ending condition)

David Anton
www.tangiblesoftwaresolutions.com
Home of the Instant C# VB.NET to C# converter
and the Instant VB C# to VB.NET converter

"MariusI" wrote:
在查看使用ms .net 2003编译器生成的IL操作码时,我偶然发现了优化(或缺少一个,具体而言)。我正在测试快速
像素操作使用Bitmap.LockBits和不安全的指针来迭代图像的像素。内循环看起来像这样:

for(int x = 0; x< _buffer.Width * _buffer.Height; x ++)
{
//在这里进行操作..
}

我注意到for循环表现得非常慢,而且ildasm透露了x< _buffer.Width * _buffer.Height"在每次迭代时计算,
导致两个虚拟调用和一个mul。 / optimize的使用没有改善这个问题,所以解决方案是在for循环之外计算
_buffer.Width * _buffer.Height。我的印象是编译器自动提升,我在这里错过了什么?
I stumbled over an optimization (or lack of one, to be specific) when viewing
IL opcodes generated by the compiler using ms .net 2003. I was testing fast
pixel manipulation using Bitmap.LockBits and unsafe pointers to iterate over
an image''s pixels. The inner-loop looked like this:

for (int x = 0; x < _buffer.Width*_buffer.Height; x++)
{
// do manipulations here..
}

I noticed how the for-loop performed extremely slow, and ildasm revealed
that the "x < _buffer.Width*_buffer.Height" was computed at each iteration,
resulting in two virtual calls and one mul. The use of /optimize did not
improve the matter, so the solution was to calculate
_buffer.Width*_buffer.Height outside of the for-loop. I was under the
impression that the compiler performed hoisting automatically, am I missing
something here?



嗨MariusI,
Hi MariusI,
for(int x = 0; x< _buffer.Width * _buffer.Height; x ++)
{
//在这里进行操作..
我注意到for循环表现得非常慢,而且ildasm透露了x<<< _buffer.Width * _buffer.Height"是在每次迭代时计算的,
for (int x = 0; x < _buffer.Width*_buffer.Height; x++)
{
// do manipulations here..
}

I noticed how the for-loop performed extremely slow, and ildasm revealed
that the "x < _buffer.Width*_buffer.Height" was computed at each iteration,




我认为它的工作原理应该如此。

你怎么说那段代码:


for(int x = 0; x< _buffer.Width * _buffer.Height; x ++)

{

//在这里进行操作..

if(_buffer.Height> 1){

_buffer.Height = _buffer.Height-1;

} < br $>
}


当然没有意义缩小_buffer但是

循环表达式也适用于这种情况。

为什么编译器必须猜测你的想法?


问候

Marcin



I think that it is working as it should be.
How do you say about that code:

for (int x = 0; x < _buffer.Width*_buffer.Height; x++)
{
// do manipulations here..
if( _buffer.Height>1 ) {
_buffer.Height=_buffer.Height-1;
}
}

Of course there is no sense to shrink a "_buffer" but
the loop expression should work in this case too.
Why the compiler have to guess what you have in mind?

Regards
Marcin


感谢您的回复。当你说不能保证时你是说一个

多线程系统可以改变_buffer的大小和宽度? (for循环中没有

代码,指的是缓冲区)。


David Anton写道:
Thanks for the reply. When you say "can''t guarantee" do you mean that a
multithreaded system could alter the _buffer size and width? (There is no
code inside the for-loop which refers to the buffer).

"David Anton" wrote:
如果编译器不能保证
_buffer.Width * _buffer.Height的值在任何循环迭代期间发生变化,那么它将会
必须每次计算。这就是C / C ++ / C#for-loop的本质。
在你希望发生这种情况的情况下使用for循环是很常见的。 (注意,VB永远不会重新计算结束条件)

David Anton
www.tangiblesoftwaresolutions.com
Instant C#VB.NET到C#转换器的主页
和即时VB C#到VB.NET转换器

" MariusI"写道:
If the compiler can''t guarantee that the value of
_buffer.Width*_buffer.Height changes during any loop iteration, then it''ll
have to be calculated each time. That is the nature of a C/C++/C# for-loop.
It''s quite common to have for-loops where you want this to occur. (note that
VB never recalculates the ending condition)

David Anton
www.tangiblesoftwaresolutions.com
Home of the Instant C# VB.NET to C# converter
and the Instant VB C# to VB.NET converter

"MariusI" wrote:
在查看使用ms .net 2003编译器生成的IL操作码时,我偶然发现了优化(或缺少一个,具体而言)。我正在测试快速
像素操作使用Bitmap.LockBits和不安全的指针来迭代图像的像素。内循环看起来像这样:

for(int x = 0; x< _buffer.Width * _buffer.Height; x ++)
{
//在这里进行操作..
}

我注意到for循环表现得非常慢,而且ildasm透露了x< _buffer.Width * _buffer.Height"在每次迭代时计算,
导致两个虚拟调用和一个mul。 / optimize的使用没有改善这个问题,所以解决方案是在for循环之外计算
_buffer.Width * _buffer.Height。我的印象是编译器自动执行吊装,我在这里错过了什么?
I stumbled over an optimization (or lack of one, to be specific) when viewing
IL opcodes generated by the compiler using ms .net 2003. I was testing fast
pixel manipulation using Bitmap.LockBits and unsafe pointers to iterate over
an image''s pixels. The inner-loop looked like this:

for (int x = 0; x < _buffer.Width*_buffer.Height; x++)
{
// do manipulations here..
}

I noticed how the for-loop performed extremely slow, and ildasm revealed
that the "x < _buffer.Width*_buffer.Height" was computed at each iteration,
resulting in two virtual calls and one mul. The use of /optimize did not
improve the matter, so the solution was to calculate
_buffer.Width*_buffer.Height outside of the for-loop. I was under the
impression that the compiler performed hoisting automatically, am I missing
something here?



这篇关于缺乏C#中的for循环优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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