2010-07-15 15 views
7

Tôi có một phương thức đơn giản trả về một Nullable Int32 từ một DataReader hơn là được xây dựng trong GetInt32.C# Hiệu suất đạt được một kiểu Nullable từ một SqlDataReader

Tôi gọi phương thức này nhiều lần và có một tình huống bất cứ lúc nào tôi có thể cạo bỏ nó sẽ có lợi.

Có ai có thể đề xuất bất kỳ cách thay thế và nhanh hơn nào để nhận được Int32 có thể vô hiệu hóa của DataReader không?

private Int32? GetNullableInt32(SqlDataReader dataReader, int fieldIndex) 
{ 
    return !dataReader.IsDBNull(fieldIndex) ? 
       dataReader.GetInt32(fieldIndex) : (Int32?)null; 
} 
+1

Tôi nghĩ rằng đó là về tốt như bạn sẽ nhận được. – LukeH

+0

Tôi nhớ đọc kiểm tra IsDBNull chậm. Điều này chạy 5 triệu lần trong khoảng 2 giây. Tôi cũng có các phương pháp tương tự cho tất cả các loại khác. Thậm chí tăng 10% trên phương pháp này sẽ giảm thời gian ồ ạt. –

+0

@Robin Day Tôi sẽ lần đầu tiên hồ sơ để tìm kiếm các cuộc tấn công hiệu suất đầu tiên - đạt được tỷ lệ phần trăm so với nỗ lực, tôi sẽ tranh luận về điều này, sẽ là một trong những mức thấp nhất mà bạn thấy. –

Trả lời

9

tôi vẻ để nhớ lại rằng nó có thể đôi khi bằng cách nhanh hơn để có được giá trị như một đối tượng và sau đó kiểm tra nếu đó là DBNull.

private Int32? GetNullableInt32(SqlDataReader dataReader, int fieldIndex) 
{ 
    object value = dataReader.GetValue(fieldIndex); 
    return value is DBNull ? (Int32?) null : (Int32) value; 
} 

Đó là ít nhất đáng để thử. Lưu ý rằng đây là giả định bạn có thể unbox thẳng đến một int ... Tôi không biết chắc đó có phải là chính xác hay không, nhưng nó sẽ dễ thấy.

Bây giờ có một cách tiếp cận mà là hơi ít an toàn - nó sẽ trả về null cho bất kỳ giá trị không nguyên, thậm chí nếu lĩnh vực này thực sự là một chuỗi, ví dụ:

private Int32? GetNullableInt32(SqlDataReader dataReader, int fieldIndex) 
{ 
    return dataReader.GetValue(fieldIndex) as Int32?; 
} 

trước đây tôi đã viết về "như" với các loại nullable không được nhanh như tôi mong đợi, nhưng điều này có thể là một trường hợp hơi khác ... một lần nữa, nó có giá trị có một đi.

Tuy nhiên, tôi thực sự ngạc nhiên nếu điều này thực sự là một nút cổ chai ... chắc chắn nhận được dữ liệu từ cơ sở dữ liệu ở nơi đầu tiên sẽ đắt hơn rất nhiều. Bạn có điểm chuẩn cho điều này?

+0

Tôi có điểm chuẩn cho điều này, và có, điều này là do không có nghĩa là phần chậm nhất của cuộc gọi, tuy nhiên, tôi đã làm tất cả những gì tôi có thể để lấy dữ liệu trở lại nhanh hơn và bây giờ chỉ tìm cách cạo vài giây cuối cùng. Tôi đang chạy thử nghiệm đối với hai phương pháp này ngay bây giờ và sẽ đăng kết quả. –

+0

+1 nghi ngờ nút cổ chai của nó cũng - rất hiếm khi mạng hoặc I/O không thực hiện được CPU. –

+0

Đang định cấu hình cho 5 triệu cuộc gọi trên mỗi phương thức. Phương pháp của tôi chạy ở 998ms Phương pháp đầu tiên của bạn chạy ở 1169ms Phương pháp thứ hai của bạn chạy ở 898ms Đó là mức tăng 10% và đủ tốt cho tôi! Cảm ơn! –

2

Mã bạn muốn tối ưu hóa (?:) sẽ không đáng kể so với I/O xung quanh.

Vì vậy, nó sẽ không nhận được bất kỳ nhanh hơn.

+1

+1 thực sự, âm thanh như một tối ưu hóa vi mô ở mức tốt nhất, OP cũng đề cập trong các ý kiến ​​rằng nó chạy 5 triệu lần trong 2 giây ... âm thanh đủ nhanh với tôi. –