集合类性能似乎是SLOOOWWWWWW [英] collection class performance seems SLOOOWWWWWW
问题描述
我在这里有一小部分代码。当button1_Click时被称为b $ b的表现相当差(~0.5秒)。唯一的事情就是我
没有真正做任何事情!在C ++中,同样的事情需要~0秒才能执行!! b $ b执行!!列表< Pumpicle>比ArrayList更快,我在访问之前将List转换为数组。它似乎就像
拆开Pumpicle类的双打。任何想法??
PumpicleContainer pc = null;
private void Form1_Load(object sender,EventArgs e)
{
pc = new PumpicleContainer();
for(int i = 0; i< 10000; i ++)
{
pc.Add(new Pumpicle());
}
pc.ToArray();
}
公共课DaublePoint
{
公共双m_x;
public double m_y;
public double m_z;
};
public class Pumpicle
{
public DaublePoint m_pos;
public double m_mass;
public Pumpicle()
{
m_pos = new DaublePoint();
}
};
类PumpicleContainer >
{
public List< Pumpicle> m_pList = new List< Pumpicle>();
Pumpicle [] m_arr = null;
public void Add(Pumpicle p)
{
m_pList.Add(p);
}
public void ToArray()
{
m_arr = m_pList.ToArray();
}
public Pumpicle GetParticle(int i )
{
返回m_arr [i];
}
}
private void button1_Click(object sender,EventArgs e)
{
pc.ToArray();
long start = System.DateTime.Now.Ticks;
int np = 0;
for(int idx = 0; idx< 20; idx ++)
{
np + = 22;
for(int i = -33; i< = 33; i ++)
{
for(int j = -33; j< = 33; j ++)
{
for(int l = 0; l< 5; l ++)
{
for(int ps = 0; ps< np; ps ++)
{
Pumpicle p = pc.GetParticle(ps);
DaublePoint pt = pm _pos;
double x = pt.m_x;
double y = pt.m_y;
double z = pt.m_z;
}
}
}
}
}
long end = System.DateTime.Now.Ticks;
MessageBox.Show(" Finished =" +((结束 - 开始)/ 1e7));
}
我注意到一对夫妇事情。
你通过那些嵌套的for循环进行了448900次迭代(而且我是
甚至不计算ps< np循环 - 谁知道这会增加什么呢。
你正在测量错误的时间。而不是
System.DateTime.Now.Ticks,在两个地方都使用System.DateTime.Now。然后
减去它们并到达TimeSpan,然后在
TimeSpan对象上调用elapsedMillis()。你现在测量它的方式,如果碰巧越过第二个边界,你可能会遇到非常不一致的执行时间。
DateTime then = System .DateTime.Now;
//你的循环在这里。
DateTime now = System.DateTime.Now;
TimeSpan ts = now - then ;
Console.WriteLine(ts.TotalMilliseconds);
Jeremiah
ia ******* @ bmtcordah.com 写道:我在这里有一小部分代码。当button1_Click时被称为性能相当差(~0.5秒)。唯一的事就是我没有真正做任何事情!在C ++中,同样的事情需要大约0秒才能执行!!列表< Pumpicle>比ArrayList快,我在访问之前将List转换为数组。它似乎就像是取消了Pumpicle类中的双打。任何想法??
PumpicleContainer pc = null;
private void Form1_Load(object sender,EventArgs e)
{
pc = new PumpicleContainer() ;
for(int i = 0; i< 10000; i ++)
{
pc.Add(new Pumpicle());
} >
pc.ToArray();
}
公共课DaublePoint
{公共双m_x;
公共双m_y;
public double m_z;
};
公共类Pumpicle
公共DaublePoint m_pos;
公共双m_mass;
public Pumpicle()
{
m_pos = new DaublePoint();
}
};
类PumpicleContainer
{
Pumpicle [] m_arr = null;
public void Add(Pumpicle p)
{
m_pList .Add(p);
}
public void ToArray()
{
m_arr = m_pList.ToArray();
}
公共Pumpicle GetParticle(int i)
{
返回m_arr [i];
}
}
私有void button1_Click(对象发送者) ,EventArgs e)
{
pc.ToArray();
long start = System.DateTime.Now.Ticks;
int np = 0 ;
for(int idx = 0; idx< 20; idx ++)
{
np + = 22;
for(int i = -33; i< = 33 ; i ++)
{
for(int j = -33; j< = 33; j ++)
{
for(int l = 0; l< 5; l ++ )
{
for(int ps = 0; ps< np; ps ++)
{/> Pumpicle p = pc.GetParticle(ps);
> DaublePoint pt = p.m_pos;
double x = pt.m_x;
double y = pt.m_y;
double z = pt.m_z;
}
}
}
}
long end = System.DateTime.Now.Ticks;
MessageBox。显示(" Finished =" +((结束 - 开始)/ 1e7));
}
ia ******* @ bmtcordah.com 写道:唯一的事情是我不是在做任何事情!在C ++中,同样的事情需要大约0秒才能执行!!
int np = 0;
for(int idx = 0; idx< 20; idx ++)
{
np + = 22;
for(int i = -33; i< = 33; i ++)
{
for(int j = -33; j< = 33; j ++)
{
for(int l = 0; l< 5; l ++)
{
for(int ps = 0; ps< np; ps ++)
{/> Pumpicle p = pc.GetParticle(ps) ;
DaublePoint pt = p.m_pos;
double x = pt.m_x;
double y = pt.m_y;
double z = pt.m_z; < $
}
}
对这样的比较非常非常小心!你是对的:
代码没有做任何有用的事情。 C ++编译器可能足够聪明
来检测只有最外层循环有任何持久效果:它
改变np。如果编译器足够聪明,知道
pc.GetParticle(ps)没有副作用,那么它可能只是简单地消除内部循环
。
你确定在C ++ pc.GetParticle中被称为
次数吗?或者它根本就没有被调用过吗?
然后它可能只是C ++编译器生成更好的代码。但是,你不能仅仅通过这样的基准来判断
而无需进一步检查。
< ia * ******@bmtcordah.com> écritdansle message de news:
11**********************@i40g2000cwc.googlegroups。 com ...
|我这里有一小部分代码。当button1_Click时是
|称性能相当差(~0.5秒)。唯一的事就是我是
|没有真正做任何事情!在C ++中,同样的事情需要~0秒才能获得
|执行!!。列表< Pumpicle>比ArrayList快,我转换
|访问前列表到数组。它似乎就像
|从Pumpicle类拆箱双打。任何想法??
1.为什么在访问之前将列表转换为数组?这需要时间!!
2.你没有取消任何东西,因为你持有双打和检索
双打。
而不是你的PumpicleContainer类,只需使用List< Pumpicle>因为它是没有任何包装类的
,看看是否有任何区别。
Joanna
-
Joanna Carter [TeamB]
顾问软件工程师
I have a small sellection of code here. When the "button1_Click" is
called the performance is quite poor (~ 0.5 sec). Only thing is I am
not really doing anything!! In C++ the same thing takes ~ 0 seconds to
execute!!. The List<Pumpicle> is faster than ArrayList and I convert
the List to an array before access. It just seems to be something like
unboxing the doubles out of the Pumpicle class. Any ideas??
PumpicleContainer pc = null;
private void Form1_Load(object sender, EventArgs e)
{
pc = new PumpicleContainer();
for (int i = 0; i < 10000; i++)
{
pc.Add(new Pumpicle());
}
pc.ToArray();
}
public class DaublePoint
{
public double m_x;
public double m_y;
public double m_z;
};
public class Pumpicle
{
public DaublePoint m_pos;
public double m_mass;
public Pumpicle()
{
m_pos = new DaublePoint();
}
};
class PumpicleContainer
{
public List<Pumpicle> m_pList = new List<Pumpicle>();
Pumpicle[] m_arr = null;
public void Add(Pumpicle p)
{
m_pList.Add(p);
}
public void ToArray()
{
m_arr = m_pList.ToArray();
}
public Pumpicle GetParticle(int i)
{
return m_arr[i];
}
}
private void button1_Click(object sender, EventArgs e)
{
pc.ToArray();
long start = System.DateTime.Now.Ticks;
int np = 0;
for (int idx = 0; idx < 20; idx++)
{
np += 22;
for (int i = -33; i <= 33; i++)
{
for (int j = -33; j <= 33; j++)
{
for (int l = 0; l < 5; l++)
{
for (int ps = 0; ps < np; ps++)
{
Pumpicle p = pc.GetParticle(ps);
DaublePoint pt = p.m_pos;
double x = pt.m_x;
double y = pt.m_y;
double z = pt.m_z;
}
}
}
}
}
long end = System.DateTime.Now.Ticks;
MessageBox.Show("Finished = " + ((end - start) / 1e7));
}
解决方案I notice a couple of things.
you''re doing 448900 iterations through those nested for loops (and I''m
not even counting the ps < np loop - who knows what that adds on).
You''re measuring time incorrectly. instead of
System.DateTime.Now.Ticks, use System.DateTime.Now in both places. Then
subtract them and arrive at a TimeSpan, then call elapsedMillis() on the
TimeSpan object. The way you measure it now, if you happen to cross a
second boundary, you could wind up with very inconsistent execution times.
DateTime then = System.DateTime.Now;
// your loop here.
DateTime now = System.DateTime.Now;
TimeSpan ts = now - then;
Console.WriteLine(ts.TotalMilliseconds);
Jeremiah
ia*******@bmtcordah.com wrote:I have a small sellection of code here. When the "button1_Click" is
called the performance is quite poor (~ 0.5 sec). Only thing is I am
not really doing anything!! In C++ the same thing takes ~ 0 seconds to
execute!!. The List<Pumpicle> is faster than ArrayList and I convert
the List to an array before access. It just seems to be something like
unboxing the doubles out of the Pumpicle class. Any ideas??
PumpicleContainer pc = null;
private void Form1_Load(object sender, EventArgs e)
{
pc = new PumpicleContainer();
for (int i = 0; i < 10000; i++)
{
pc.Add(new Pumpicle());
}
pc.ToArray();
}
public class DaublePoint
{
public double m_x;
public double m_y;
public double m_z;
};
public class Pumpicle
{
public DaublePoint m_pos;
public double m_mass;
public Pumpicle()
{
m_pos = new DaublePoint();
}
};
class PumpicleContainer
{
public List<Pumpicle> m_pList = new List<Pumpicle>();
Pumpicle[] m_arr = null;
public void Add(Pumpicle p)
{
m_pList.Add(p);
}
public void ToArray()
{
m_arr = m_pList.ToArray();
}
public Pumpicle GetParticle(int i)
{
return m_arr[i];
}
}
private void button1_Click(object sender, EventArgs e)
{
pc.ToArray();
long start = System.DateTime.Now.Ticks;
int np = 0;
for (int idx = 0; idx < 20; idx++)
{
np += 22;
for (int i = -33; i <= 33; i++)
{
for (int j = -33; j <= 33; j++)
{
for (int l = 0; l < 5; l++)
{
for (int ps = 0; ps < np; ps++)
{
Pumpicle p = pc.GetParticle(ps);
DaublePoint pt = p.m_pos;
double x = pt.m_x;
double y = pt.m_y;
double z = pt.m_z;
}
}
}
}
}
long end = System.DateTime.Now.Ticks;
MessageBox.Show("Finished = " + ((end - start) / 1e7));
}
ia*******@bmtcordah.com wrote:Only thing is I am not really doing anything!! In C++ the same thing takes ~ 0 seconds to execute!!. int np = 0;
for (int idx = 0; idx < 20; idx++)
{
np += 22;
for (int i = -33; i <= 33; i++)
{
for (int j = -33; j <= 33; j++)
{
for (int l = 0; l < 5; l++)
{
for (int ps = 0; ps < np; ps++)
{
Pumpicle p = pc.GetParticle(ps);
DaublePoint pt = p.m_pos;
double x = pt.m_x;
double y = pt.m_y;
double z = pt.m_z;
}
}
}
}
}
Be very, very careful about comparisons like this! You are right: the
code isn''t doing anything useful. The C++ compiler may be smart enough
to detect that only the outermost loop has any lasting effect: it
changes np. If the compiler is clever enough to know that
pc.GetParticle(ps) has no side-effects, then it may simply eliminate
the inner loops altogether.
Are you sure that in C++ pc.GetParticle is being called the number of
times you expect? Or is it never called at all?
Then again it may simply be that the C++ compiler produces much better
code. However, you can''t tell just from doing a benchmark like this
without further checks.
<ia*******@bmtcordah.com> a écrit dans le message de news:
11**********************@i40g2000cwc.googlegroups. com...
|I have a small sellection of code here. When the "button1_Click" is
| called the performance is quite poor (~ 0.5 sec). Only thing is I am
| not really doing anything!! In C++ the same thing takes ~ 0 seconds to
| execute!!. The List<Pumpicle> is faster than ArrayList and I convert
| the List to an array before access. It just seems to be something like
| unboxing the doubles out of the Pumpicle class. Any ideas??
1. Why convert the list to an array before access ? this takes time !!
2. You are not unboxing anything as you are holding doubles and retrieving
doubles.
Instead of your PumpicleContainer class, just use a List<Pumpicle> as it is
without any wrapper class and see if that makes any difference.
Joanna
--
Joanna Carter [TeamB]
Consultant Software Engineer
这篇关于集合类性能似乎是SLOOOWWWWWW的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!