Tôi quyết định kiểm tra hiệu suất của từng phương pháp bằng cách sử dụng bộ sưu tập 1.000.000 đối tượng. Các đối tượng là một trong số: một số nguyên, một lớp, Không có gì hoặc DBNull.Value. Cùng một bộ sưu tập đã được sử dụng cho mỗi bài kiểm tra, và tôi đã kiểm tra từng phương pháp 50 lần.
"" & x
Điều này thực sự không hiệu quả với tất cả các đối tượng. Nó hoạt động cho DBNull.Value và Nothing, nhưng cố gắng sử dụng phương thức này chỉ với bất kỳ đối tượng ol 'nào sẽ gây ra một InvalidCastException. Thật thú vị, CStr (DBNull.Value) ném một InvalidCastException, vì vậy tôi không chắc chắn tại sao nó hoạt động.
Kết quả với đối tượng tùy chỉnh: N/A
Kết quả w/o đối tượng tùy chỉnh: avg 126,7 ms, trung bình 126 ms
If(x, "").ToString()
Kết quả với đối tượng tùy chỉnh: avg 140,46 ms, trung bình 138 ms
Kết quả w/o đối tượng tùy chỉnh: avg 69.32 ms, trung bình 69 ms
Convert.ToString()
Kết quả với đối tượng tùy chỉnh: avg 171,54 ms, trung bình 171 ms
Kết quả w/o đối tượng tùy chỉnh: avg 112,14 ms, trung bình 112 ms
Vì vậy, có vẻ như là If(x, "").ToString()
nhanh hơn một chút đối với một tập hợp rất lớn các bản ghi, nhưng điều đó sẽ cần phải được cân bằng với nhiều hơn p2e của Convert.ToString()
tùy chọn chuyển đổi rful. Cảm ơn câu trả lời.
Dưới đây là đoạn code tôi dùng để thử nghiệm:
Option Strict Off
Module Module1
Sub Main()
Dim l_objectArray = Enumerable.Range(0, 1000000).Select(Function(x) GetObject(x)).ToArray()
Dim l_stopWatch As New Stopwatch()
Dim l_testResults As New List(Of Long)
Dim l_testIterations As Integer = 50
Dim l_displayValue As String
Do
' --------------------
'Console.WriteLine()
'Console.WriteLine("Conversion using string concatenation")
'l_testResults.Clear()
'For iteration = 0 To l_testIterations - 1
' l_stopWatch.Start()
' For Each o In l_objectArray
' l_displayValue = "" & o
' Next
' l_stopWatch.Stop()
' l_testResults.Add(l_stopWatch.ElapsedMilliseconds)
' l_stopWatch.Reset()
'Next
'Console.WriteLine()
'Console.WriteLine("Average: " & l_testResults.Average())
'Console.WriteLine("Median: " & GetMedian(l_testResults.ToArray()))
' --------------------
Console.WriteLine()
Console.WriteLine("Conversion using Object.ToString()")
l_testResults.Clear()
For iteration = 0 To l_testIterations - 1
l_stopWatch.Start()
For Each o In l_objectArray
l_displayValue = If(o, "").ToString()
Next
l_stopWatch.Stop()
l_testResults.Add(l_stopWatch.ElapsedMilliseconds)
l_stopWatch.Reset()
Next
Console.WriteLine()
Console.WriteLine("Average: " & l_testResults.Average())
Console.WriteLine("Median: " & GetMedian(l_testResults.ToArray()))
' --------------------
Console.WriteLine()
Console.WriteLine("Conversion using Convert.ToString(x)")
l_testResults.Clear()
For iteration = 0 To l_testIterations - 1
l_stopWatch.Start()
For Each o In l_objectArray
l_displayValue = Convert.ToString(o)
Next
l_stopWatch.Stop()
l_testResults.Add(l_stopWatch.ElapsedMilliseconds)
l_stopWatch.Reset()
Next
Console.WriteLine()
Console.WriteLine("Average: " & l_testResults.Average())
Console.WriteLine("Median: " & GetMedian(l_testResults.ToArray()))
' --------------------
Console.WriteLine()
Console.Write("Exit? (y/n): ")
Dim l_key = Console.ReadKey(False)
If l_key.Key = ConsoleKey.Y Then
Exit Sub
End If
Loop
End Sub
Private Function GetMedian(ByVal values As Long()) As Long
Array.Sort(values)
If values.Length Mod 2 = 0 Then
Return (values(values.Length/2) + values(values.Length/2 - 1))/2
Else
Return values(CInt(Math.Floor(values.Length/2)))
End If
End Function
Private Function GetObject(ByVal someNumber As Integer) As Object
Select Case someNumber Mod 4
Case 0
Return someNumber
Case 1
Return New SomeClass(someNumber)
'Return Nothing
Case 2
Return DBNull.Value
Case Else
Return Nothing
End Select
End Function
Private Class SomeClass
Private _seed As Integer
Public Sub New(ByVal seed As Integer)
_seed = seed
End Sub
Public Overrides Function ToString() As String
Return _seed.ToString()
End Function
End Class
End Module
Bạn có biết nếu điều này là tiêu chuẩn khuyến cáo của Microsoft? Bất kỳ ý tưởng gì, nếu có, chi phí được giới thiệu so với hai phương pháp khác? Tôi không phải là một ninja CLR, vì vậy tôi không thể so sánh chúng ở cấp mã byte. – JDB
Tôi nghĩ rằng trong điều khoản của những điều hiệu suất không thay đổi một cách hợp lý, tốt hơn là an toàn hơn. –
Cảm ơn - đây là câu trả lời hữu ích nhất. Tôi đã thêm một câu trả lời với kết quả kiểm tra của tôi và về cơ bản nó đã xác nhận đề xuất của bạn. – JDB