我有这个代码,在交换UsingAs和UsingCast的顺序时,它们的性能也会交换。
using System;
using System.Diagnostics;
using System.Linq;
using System.IO;
class Test
{
const int Size = 30000000;
static void Main()
{
object[] values = new MemoryStream[Size];
UsingAs(values);
UsingCast(values);
Console.ReadLine();
}
static void UsingCast(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
if (o is MemoryStream)
{
var m = (MemoryStream)o;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("Cast: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
static void UsingAs(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
if (o is MemoryStream)
{
var m = o as MemoryStream;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("As: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
}
输出:
As: 0 : 322
Cast: 0 : 281
这样做......
UsingCast(values);
UsingAs(values);
...结果:
Cast: 0 : 322
As: 0 : 281
这样做......
UsingAs(values);
...结果:
As: 0 : 322
这样做的时候:
UsingCast(values);
...结果:
Cast: 0 : 322
除了独立运行它们之外,如何使缓存无效,以便第二个被基准测试的代码不会收到第一个代码的缓存内存?
除了标杆之外,只是喜欢现代处理器做这种缓存魔术的事实: - )
[编辑]
建议尝试这个更快的代码(据说)......
static void UsingAsAndNullTest(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
var m = o as MemoryStream;
if (m != null)
{
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("As and null test: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
......结果如下:
As and null test: 0 : 342
比上面的两个代码慢
[编辑]:
建议将每个例程交给他们自己的副本......
static void UsingAs(object[] values)
{
object[] a = values.ToArray();
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in a)
{
if (o is MemoryStream)
{
var m = o as MemoryStream;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("As: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
static void UsingCast(object[] values)
{
object[] a = values.ToArray();
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in a)
{
if (o is MemoryStream)
{
var m = (MemoryStream)o;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("Cast: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
...输出:
Cast: 0 : 282
As: 0 : 282
现在他们有相同的结果,感谢Remus!
独立地运行Cast和As,它们也产生相同的结果(即282)。现在,至于他们为什么变得更快(从322到282毫秒)当他们交给他们自己的阵列副本时,我无法做出任何结果:-)这完全是另一个故事< / p>
答案 0 :(得分:1)
如果你想从图片中取出L2缓存和TLB未命中,那么只需在相同大小的不同MemoryStream上调用第二个测试。