例如
Aclass myAclass = new Aclass();
for(int i=0;i<n;i++)
{
myAclass.load(i);
myAclass.do();
myAclass.clear() // clear the state of myAclass, rdy for next iteration.
}
或者,如果我将`myAclass.load()嵌入到类构造函数中,并且做如下:
for(int i=0;i<n;i++)
{
Aclass myAclass = new Aclass(i);
myAclass.do();
}
那么哪种方式更好的做法? 顺便说一句,标题似乎不适合内容,帮助我更合适的标题。
注意:Aclass的构造函数是微不足道的,Load()不是,Clear()是微不足道的 (当然第二个例子中的构造函数并不重要,因为它会触发Load()。)
答案 0 :(得分:3)
通常,在C#中,垃圾收集器将为您处理所有这些。
如果你想在完成它后明确处理一个对象,请确保它实现IDisposable并在你的循环中执行以下操作:
for (int i = 0; i < infinity; i ++)
{
using (MyClass myObject = new MyClass(i))
{
myObject.DoWork();
...
} // The object will dispose here
}
答案 1 :(得分:3)
我要逆势而行,并建议采取第二种方式(假设琐碎的建设)。垃圾收集器在短期对象上茁壮成长,第二种方式
答案 2 :(得分:2)
没有办法告诉哪种方法在性能方面最好,这取决于课程的实施。
现在,作为一般规则,您应该避免使用可变对象,因此重复使用该类的相同实例来执行其他操作通常不是一个好主意。所以我赞成第二种方法。当然,如果类的初始化是一项昂贵的操作,第一种方法会更快......
至于内存使用情况,第二种方法会在内存中创建更多实例,但它们最终会被GC收集,因此它不应成为问题。唯一的缺点是它给GC带来了更大的压力,因此如果有很多次迭代,它可能会对性能产生负面影响。
答案 3 :(得分:1)
对于性能,它实际上取决于构造Aclass
类实例与调用Clear()
的成本相比多少,您可以通过运行具有10000次迭代的循环来测试更好的行为并使用System.Diagnostics.Stopwatch
来测试哪个是更好的性能。所以:
int n = 100000;
Stopwatch watch = Stopwatch.StartNew();
Aclass myAclass = new Aclass();
for(int i=0; i<n; i++)
{
myAclass.load(i);
myAclass.do();
myAclass.clear() // clear the state of myAclass, rdy for next iteration.
}
watch.Stop();
Console.WriteLine(watch.ElampsedMilliseconds);
watch.Reset();
watch.Start();
for(int i=0;i<n;i++)
{
Aclass myAclass = new Aclass(i);
myAclass.do();
}
watch.Stop();
Console.WriteLine(watch.ElampsedMilliseconds);
编辑:作为@Mark评论对,我们应首先调用函数而不进行时间测量,然后运行时间测试。这样:
AClass foo = new AClass();
foo.Load(0);
foo.do();
foo.clear();
然后上面发布的测试代码“由int n = 100000;
”开始。
答案 4 :(得分:1)
很大程度上取决于Aclass的结构。
第一个选项通常会使用更少的内存,因为您正在重用类实例。我通常会说因为如果Aclass的状态包含很多引用类型(字符串,其他类),那么'清除'它(将这些引用设置为null)仍然会将这些对象留在堆上以便清理垃圾收集器。由于清除对象所花费的时间,它也可能更慢(并且可能更容易出错)。
第二种方式通常会更快(.net中的分配确实非常非常快),但通常会使用更多内存。这是.net,java和其他垃圾收集平台中的常见模式,因为垃圾收集器的意图是模拟具有无限内存的环境(参见Raymond Chen's article。)
答案 5 :(得分:0)
就性能而言,第一种选择是最佳选择。在第二个for循环中,每次遍历循环时,将在堆上实例化并分配新的Aclass实例。您将在CLR将要垃圾收集的堆上留下此类的许多实例。垃圾收集会减慢正在运行的程序的执行速度,因为必须占用宝贵的CPU周期才能释放内存。
想想看,如果循环迭代1000次,它将在堆上留下1000个对象。即使每个对象是5mb甚至2MB,这也会大大减慢你的程序。排在第一位。作为旁注,我更喜欢load方法而不是构造函数,因为我发现它更容易理解你在使用该类做什么。