缺乏C#中的for循环优化 [英] Lacking for-loop optimization in C#
问题描述
我在查看
编译器使用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屋!