이 질문은 때때로 나타나지만 만족스러운 답변을 보지 못했습니다.
일반적인 패턴은 다음과 같습니다 (행은 DataRow입니다 ).
if (row["value"] != DBNull.Value)
{
someObject.Member = row["value"];
}
첫 번째 질문은 더 효율적인 것입니다 (조건을 뒤집 었습니다).
row["value"] == DBNull.Value; // Or
row["value"] is DBNull; // Or
row["value"].GetType() == typeof(DBNull) // Or... any suggestions?
이것은 .GetType ()이 더 빠르다는 것을 나타내지 만 컴파일러는 내가 모르는 몇 가지 트릭을 알고 있습니까?
두 번째 질문은 row [ "value"]의 값을 캐싱 할 가치가 있습니까, 아니면 컴파일러가 인덱서를 최적화합니까?
예를 들면 다음과 같습니다.
object valueHolder;
if (DBNull.Value == (valueHolder = row["value"])) {}
노트:
- 행 [ "값"]이 존재합니다.
- 열의 열 인덱스를 알지 못하므로 열 이름 조회입니다.
- DBNull을 확인한 다음 할당 (조기 최적화 등이 아닌)에 대해 구체적으로 묻습니다.
몇 가지 시나리오 (초, 10,000,000 회 시도)를 벤치마킹했습니다.
row["value"] == DBNull.Value: 00:00:01.5478995
row["value"] is DBNull: 00:00:01.6306578
row["value"].GetType() == typeof(DBNull): 00:00:02.0138757
Object.ReferenceEquals는 "=="와 동일한 성능을 갖습니다.
가장 흥미로운 결과? 대소 문자를 기준으로 열 이름이 일치하지 않으면 (예 : "value"대신 "Value") 문자열의 길이가 약 10 배 길어집니다.
row["Value"] == DBNull.Value: 00:00:12.2792374
이야기의 교훈은 인덱스로 열을 찾을 수 없다면 인덱서에 공급하는 열 이름이 DataColumn의 이름과 정확히 일치하는지 확인하는 것입니다.
값 캐싱도 거의 두 배 빠릅니다.
No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920
따라서 가장 효율적인 방법 은 다음과 같습니다 .
object temp;
string variable;
if (DBNull.Value != (temp = row["value"]))
{
variable = temp.ToString();
}
IDataRecord
확장 기능 을 좋아했을 것 입니다.