Ben sadece null edilebilir türleri ile ilgilenen Derinlik C # Bölüm 4 gözden geçiriyorum, ve ben yazmak için izin verir "as" operatörü kullanma hakkında bir bölüm ekliyorum:
object o = ...;
int? x = o as int?;
if (x.HasValue)
{
... // Use x.Value in here
}
Bunun gerçekten düzgün olduğunu ve C # 1 eşdeğeri üzerindeki performansı artırabileceğini düşündüm, "is" ve ardından bir alçı kullanarak - sonuçta, bu şekilde sadece bir kez dinamik tip kontrolü ve daha sonra basit bir değer kontrolü istemeliyiz .
Ancak durum böyle değil. Temelde bir nesne dizisi içindeki tüm tamsayıları toplayan aşağıdaki örnek bir test uygulaması ekledim - ancak dizi çok sayıda boş başvuru ve dize başvurusunun yanı sıra kutulu tamsayılar içeriyor. Karşılaştırma ölçütü, C # 1'de kullanmanız gereken kodu, "as" operatörünü kullanan kodu ve yalnızca bir LINQ çözümünü başlatması için ölçer. Şaşkınlığım için, C # 1 kodu bu durumda 20 kat daha hızlı - ve hatta LINQ kodu (dahil olan yineleyiciler göz önüne alındığında daha yavaş olmasını beklerdim) "as" kodunu atıyor.
isinst
Null olabilecek türler için .NET uygulaması gerçekten yavaş mı? unbox.any
Soruna neden olan ek mi? Bunun başka bir açıklaması var mı? Şu anda bunu performansa duyarlı durumlarda kullanmaya karşı bir uyarı eklemem gerekecek gibi geliyor ...
Sonuçlar:
Oyuncular: 10000000: 121
As: 10000000: 2211
LINQ: 10000000: 2143
Kod:
using System;
using System.Diagnostics;
using System.Linq;
class Test
{
const int Size = 30000000;
static void Main()
{
object[] values = new object[Size];
for (int i = 0; i < Size - 2; i += 3)
{
values[i] = null;
values[i+1] = "";
values[i+2] = 1;
}
FindSumWithCast(values);
FindSumWithAs(values);
FindSumWithLinq(values);
}
static void FindSumWithCast(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
if (o is int)
{
int x = (int) o;
sum += x;
}
}
sw.Stop();
Console.WriteLine("Cast: {0} : {1}", sum,
(long) sw.ElapsedMilliseconds);
}
static void FindSumWithAs(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
int? x = o as int?;
if (x.HasValue)
{
sum += x.Value;
}
}
sw.Stop();
Console.WriteLine("As: {0} : {1}", sum,
(long) sw.ElapsedMilliseconds);
}
static void FindSumWithLinq(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = values.OfType<int>().Sum();
sw.Stop();
Console.WriteLine("LINQ: {0} : {1}", sum,
(long) sw.ElapsedMilliseconds);
}
}
as
null olabilecek türlerde kullanabileceğinizi öğrendim . Diğer değer türlerinde kullanılamayacağı için ilginç. Aslında daha şaşırtıcı.
as
bir türe döküm yapmaya çalışır ve başarısız olursa null değerini döndürür. Değer türlerini null olarak ayarlayamazsınız