У меня есть этот код, что при изменении порядка использованияAs и 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
Кроме того, чтобы запускать их независимо, как аннулировать кэш, чтобы второй тестируемый код не получал кешированную память первого кода?
Не говоря о бенчмаркинге, просто любил тот факт, что современные процессоры делают эту магию кеширования:
[EDIT]
Как советуют попробовать этот более быстрый код (предположительно) ...
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
Медленнее, чем два кода выше
[EDIT]:
Как советовали вручать каждой рутине свою копию ...
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
Теперь у них одинаковые результаты, спасибо, Ремус!
Запуск Cast и As независимо друг от друга, они также дают одинаковый результат (т.е. 282). Теперь, что касается того, почему они становятся быстрее (с 322 до 282 миллисекунд), когда им вручают свою собственную копию массива, я ничего не могу из этого сделать :-) Это совсем другая история