Which is more efficient Cstr(value) or value.ToString()

无人久伴 提交于 2019-12-19 05:47:47

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!