in
刚开始学习 C#,我正在测试使用修饰符和不使用修饰符将参数传递给方法之间的任何性能差异。所以我写了下面的代码,它的行为很奇怪,
class Program
{
static void Main(string[] args)
{
int n=5;
float sum=0;
for(int i=1; i<=n; i++){
sum+=VectorPerfGain();
Thread.Sleep(200);
}
Console.WriteLine("Avg Performance Gain Ref/Normal="+sum/5+"%");
}
static float VectorPerfGain()
{
float t_ref, t_normal;
List<Vector> vectors;
Stopwatch watch;
//--------------------------------------BLOCK-A---------------------------//
vectors=new List<Vector>(){
new Vector(67.3,34.2), new Vector(38.3,98.12)
};
watch=Stopwatch.StartNew();
for(int i=1; i<10000000; i++){
vectors.Add(Vector.GetNew(vectors[vectors.Count-1],vectors[vectors.Count-2]));
}
watch.Stop();
t_normal=watch.ElapsedMilliseconds;
//--------------------------------------BLOCK-B---------------------------//
vectors=new List<Vector>(){
new Vector(67.3,34.2), new Vector(38.3,98.12)
};
watch=Stopwatch.StartNew();
for(int i=1; i<10000000; i++){
vectors.Add(Vector.GetNewByRef(vectors[vectors.Count-1],vectors[vectors.Count-2]));
}
watch.Stop();
t_ref=watch.ElapsedMilliseconds;
return (t_normal-t_ref)*100/t_normal;
}
struct Vector{
public double x, y;
public Vector(double x, double y){ this.x=x; this.y=y; }
public static Vector GetNew(Vector a, Vector b)
{
return new Vector(a.x+b.x,a.y+b.y);
}
public static Vector GetNewByRef(in Vector a, in Vector b)
{
return new Vector(a.x+b.x,a.y+b.y);
}
}
}
我通过调用Vector.GetNewByRef()
相对于该Vector.GetNew()
方法的方法来测量性能增益的百分比。
当我运行上面的代码时,我平均获得了大约-0.5%的性能增益,波动大约为1-2% 。
现在,当我移动BLOCK-B
之前BLOCK-A
,VectorPerfGain()
平均性能增益会以3-4%的波动跃升至-28% !
等等。
当我更改struct Vector
为class Vector
并运行 usingBLOCK-A
之前BLOCK-B
,平均性能增益为-21%,波动为2-3%Vector
(即与a时发生的情况相反struct
)。
然后,当我在性能大幅波动5-25%BLOCK-B
之前运行代码时(注意这次是正数),所以这里的平均值不可靠。BLOCK-A
我遇到的最重要的问题是,为什么简单地改变两个相互独立的代码块的顺序会如此剧烈地改变结果?