Saya baru saja merevisi bab 4 dari C # di Kedalaman yang berkaitan dengan jenis nullable, dan saya menambahkan bagian tentang menggunakan operator "sebagai", yang memungkinkan Anda untuk menulis:
object o = ...;
int? x = o as int?;
if (x.HasValue)
{
... // Use x.Value in here
}
Saya pikir ini benar-benar rapi, dan itu bisa meningkatkan kinerja lebih dari setara C # 1, menggunakan "is" diikuti oleh pemain - setelah semua, dengan cara ini kita hanya perlu meminta pemeriksaan tipe dinamis sekali, dan kemudian pemeriksaan nilai sederhana .
Namun, ini tampaknya bukan masalahnya. Saya telah memasukkan contoh aplikasi uji di bawah ini, yang pada dasarnya menjumlahkan semua bilangan bulat dalam sebuah array objek - tetapi array tersebut berisi banyak referensi nol dan referensi string serta bilangan bulat kotak. Tolok ukur mengukur kode yang harus Anda gunakan dalam C # 1, kode menggunakan operator "sebagai", dan hanya untuk menendang solusi LINQ. Yang mengherankan saya, kode C # 1 adalah 20 kali lebih cepat dalam kasus ini - dan bahkan kode LINQ (yang saya harapkan akan lebih lambat, mengingat iterator yang terlibat) mengalahkan kode "sebagai".
Apakah implementasi .NET isinst
untuk tipe nullable benar-benar lambat? Apakah ini tambahanunbox.any
yang menyebabkan masalah? Apakah ada penjelasan lain untuk ini? Saat ini rasanya saya harus memasukkan peringatan untuk tidak menggunakan ini dalam situasi sensitif kinerja ...
Hasil:
Cast: 10000000: 121
As: 10000000: 2211
LINQ: 10000000: 2143
Kode:
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
jenis nullable. Menarik, karena tidak dapat digunakan pada tipe nilai lainnya. Sebenarnya, lebih mengejutkan.
as
upaya untuk melakukan cast ke suatu tipe dan jika gagal maka ia mengembalikan nol. Anda tidak dapat mengatur tipe nilai menjadi null