问题
I am wondering which is more efficient, using CStr() or object.toString(). The reason I ask this is because I though all that CStr() done was to invoke the .ToString() method on the object it was dealing with.
But when recently using a generic method without any type constraints I had to use object.ToString() instead of CStr(object), the following is purely an example to illustrate the issue.
Public Function IDFromObject(Of ID_TYPE)(ByVal value As ID_TYPE) As String
Return value.ToString
End Function
Compiled as expected, but the following did not using CStr(). It gave an compilation error value of type ID_TYPE cannot be converted to string. But it obviously can using .ToString()
Public Function IDFromObject(Of ID_TYPE)(ByVal value As ID_TYPE) As String
Return CStr(value)
End Function
回答1:
From here (couldn't say it any better):
CStr is a keyword, whereas ToString is a function (method). CStr is compiled inline and it creates code depending on the type of the passed object. It's mainly there for people being used to it from previous VB versions. I haven't used CStr in .Net anymore (because it's not obvious what it does in which situations and it's also not very well documented).
The difference depends on which ToString function you use. Every type can have it's own implementation.
回答2:
For readability sake, if I were in the need to write code in VB.NET (I am a C# programmer), I would avoid the VB specific keywords/functions as much as possible. By using .NET classes and methods only, your code will be more understandable by people used to develop in other .NET languages. Not to mention that these functions are there mainly for compatibility with VB6 and they look a bit out of place compared to the .NET way of doing things.
Of course there may be reasonable exceptions, sometimes VB.NET really makes very easy to do certain tasks and it can be convenient to take advantage of this; but as a genereal rule I would not use any VB.NET specific function.
回答3:
Here is the code from the above test, but redone with System.Diagnostics.Stopwatch, and removing the Console.write bottleneck.
It turns out directcasting is fastest(as well it should be - it isn't doing anything in this case. However its a trivialised example because its rare you would want to convert a string to a string. Converting Module Module1 Sub Main()
Dim obj As Object = "asdfsdasdfsadfasdfasdfasdfsdasdfsadfasdfasdfdafsdfasd"
Dim LL As New List(Of String), SWW As System.Diagnostics.Stopwatch
LL.Clear()
SWW = Stopwatch.StartNew()
For i = 0 To Short.MaxValue
LL.Add(obj.ToString)
Next
Console.WriteLine("obj.ToString took {0}.", SWW.ElapsedTicks)
LL.Clear()
SWW = Stopwatch.StartNew()
For i = 0 To Short.MaxValue
LL.Add(CStr(obj))
Next
Console.WriteLine("CStr(obj) took {0}.", SWW.ElapsedTicks)
LL.Clear()
SWW = Stopwatch.StartNew()
For i = 0 To Short.MaxValue
LL.Add(DirectCast(obj, String))
Next
Console.WriteLine("DirectCast(obj, String) took {0}.", SWW.ElapsedTicks)
Console.WriteLine("---------------- Integer To String ----------- ")
obj = 15522
LL.Clear()
SWW = Stopwatch.StartNew()
For i = 0 To Short.MaxValue
LL.Add(obj.ToString)
Next
Console.WriteLine("obj.ToString took {0}.", SWW.ElapsedTicks)
LL.Clear()
SWW = Stopwatch.StartNew()
For i = 0 To Short.MaxValue
LL.Add(CStr(obj))
Next
Console.WriteLine("CStr(obj) took {0}.", SWW.ElapsedTicks)
LL.Clear()
SWW = Stopwatch.StartNew()
For i = 0 To Short.MaxValue
Dim str As String = TryCast(obj, String)
' This obviously fails, as obj is not a string, which is why it is so fast.. str is then nothing
LL.Add(str)
Next
Console.WriteLine("DirectCast(obj, String) took {0}.", SWW.ElapsedTicks)
Console.Read()
End Sub
End Module
My results:
(string ) : ToString : 2288; CStr: 2275; DirectCast: 1586
(integer) : ToString : 10526; CStr: 13184; TryCast: 982
回答4:
One BIG difference between CStr as ToString is handling of Enum variables.
CStr returns the underlying number e.g. "2" and ToString returns the Enum name e.g. "LeftToRight"
回答5:
They are two completely different things, CStr is an overloaded function that converts the data within certain types into a string while ToString calls a method that all .net objects have and which you can override but which by default contains the name of the object. ToString will only return the data of a type if it has been overridden to do so.
回答6:
Here is the results of a little test I made:
Module Module1
Sub Main()
Dim obj As Object = "asdfsdasdfsadfasdfasdfasdfsdasdfsadfasdfasdfdafsdfasd"
Dim y = Now, z = Now
y = Now
For i = 0 To Short.MaxValue
Console.WriteLine(obj.ToString)
Next
z = Now
Dim time1 = z - y
y = Now
For i = 0 To Short.MaxValue
Console.WriteLine(CStr(obj))
Next
z = Now
Dim time2 = z - y
y = Now
For i = 0 To Short.MaxValue
Console.WriteLine(DirectCast(obj, String))
Next
z = Now
Dim time3 = z - y
Console.WriteLine("obj.ToString took {0}.", time1)
Console.WriteLine("CStr(obj) took {0}.", time2)
Console.WriteLine("DirectCast(obj, String) took {0}.", time3)
Console.Read()
End Sub
End Module
Results:
obj.ToString() took 00:00:06.9303964.
CStr(obj) took 00:00:06.8763933.
DirectCast(obj, String) took 00:00:06.8903941.
Which makes it certain that CStr
is the fastest, then goes DirectCast
and finally ToString
with highes performance cost.
回答7:
I tried to time the following two subroutines (forgive my variable naming):
For i As Integer = 1 To 1000
For j As Integer = 1 To 65536
eee = aaa.ToString()
eee = bbb.ToString()
eee = ccc.ToString()
eee = ddd.ToString()
eee = Nothing
Next
Next
and
For i As Integer = 1 To 1000
For j As Integer = 1 To 65536
eee = CStr(aaa)
eee = CStr(bbb)
eee = CStr(ccc)
eee = CStr(ddd)
eee = Nothing
Next
Next
where
Dim aaa As Integer = 1233
Dim bbb As Single = 445.234234234
Dim ccc As Double = 234234.234457634
Dim ddd As Decimal = 1231.3466734523424
Dim eee As String = Nothing
the ToString()
loop takes 62 seconds and the CStr()
loop takes 64 seconds. It is really not a huge impact in my opinion, if you are only dealing with numbers. I disabled any compiler optimization during the timing process.
回答8:
CStr(object) is a cast (equivalent to (string)object in C#) and will throw esxception if given a null obejct or an object that cannot be casted to string. However .ToString() will work on any type of object (since it implemented in the Object class) and if not overridden by the current class will return the base ToString() method. In your case you must override ToString() method in your ID_TYPE class and return the string you need.
来源:https://stackoverflow.com/questions/979880/which-is-more-efficient-cstrvalue-or-value-tostring