난 그냥 nullable 형식을 다루는 심도 C #의 4 장을 수정하고 "as"연산자를 사용하여 쓸 수있는 섹션을 추가하고 있습니다 :
object o = ...;
int? x = o as int?;
if (x.HasValue)
{
... // Use x.Value in here
}
나는 이것이 정말로 깔끔하다고 생각했으며 "is"와 캐스트를 사용하여 C # 1에 비해 성능을 향상시킬 수 있다고 생각했다. .
그러나 이것은 사실이 아닙니다. 아래에 샘플 테스트 응용 프로그램이 포함되어 있습니다. 기본적으로 객체 배열 내의 모든 정수를 합산합니다.하지만 배열에는 많은 null 참조와 문자열 참조 및 박스형 정수가 포함됩니다. 벤치 마크는 C # 1에서 사용해야하는 코드, "as"연산자를 사용하는 코드 및 LINQ 솔루션을 시작하는 데 사용됩니다. 놀랍게도 C # 1 코드는이 경우 20 배 더 빠릅니다. 심지어 LINQ 코드 (반복자를 고려할 때 느려질 것으로 예상 됨)도 "as"코드를 능가합니다.
isinst
nullable 형식 에 대한 .NET 구현이 정말 느립니까? unbox.any
문제를 일으키는 추가 항목 입니까? 이것에 대한 또 다른 설명이 있습니까? 현재 성능에 민감한 상황에서 이것을 사용하지 않는 것에 대한 경고를 포함해야한다고 생각합니다 ...
결과 :
시전 : 10000000 : 121
As : 10000000 : 2211
LINQ : 10000000 : 2143
암호:
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
은 nullable 유형에 사용할 수 있다는 것을 배웠습니다 . 다른 값 유형에는 사용할 수 없으므로 흥미 롭습니다. 실제로, 더 놀라운.
as
하고 유형으로 캐스트하려고 시도하면 실패하면 null을 반환합니다. 값 유형을 null로 설정할 수 없습니다