คำถามนี้เกิดขึ้นเป็นครั้งคราว แต่ฉันไม่เห็นคำตอบที่น่าพอใจ
รูปแบบทั่วไปคือ (แถวคือ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 () ควรจะเร็วกว่านี้ แต่บางทีคอมไพเลอร์ก็รู้เทคนิคเล็กน้อยที่ฉันไม่ต้องการ
คำถามที่สองมันคุ้มค่าที่จะแคชค่าของแถว ["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" จะใช้เวลานานกว่าประมาณสิบเท่า (สำหรับสตริง):
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
ส่วนขยายที่รัก