Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

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

Writer Matthew Harrington

I am wondering which is more efficient, using CStr() or object.toString(). The reason I ask this is because I thought all that CStr() does is 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 use .ToString()

Public Function IDFromObject(Of ID_TYPE)(ByVal value As ID_TYPE) As String Return CStr(value)
End Function
2

9 Answers

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.

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.

2

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"

Late answer, but no one else bothered to check or cite the Visual Basic documentation, and it recommends the opposite of what most of these answers do. This is straight from the Microsoft documentation:

As a rule, you should use the Visual Basic type conversion functions in preference to the .NET Framework methods such as ToString(), either on the Convert class or on an individual type structure or class. The Visual Basic functions are designed for optimal interaction with Visual Basic code, and they also make your source code shorter and easier to read.

That said, sometimes there are differences between what CStr and ToString will return, so performance and readability aren't the only considerations. There is an excellent answer on another question that describes when and why this is the case. Reproduced here:

The ToString method is a standard public method that returns a String. It is a method that is defined by the base Object type as overrideable. Each class can, therefore, override that method to return anything that it wants. It is quite common for classes to override the ToString method to make it return a nice human-readable description of the object.

CStr, on the other hand, is a casting operator. It is shorthand for CType(x, String). The casting operator, like many other operators, can be overridden by any class. Normally, though, you want casting operations to return the closest representation of the actual value of the original object, rather than a descriptive string.

It is not unusual then, that you may want ToString to return a different result than CStr. In the case of an enum, each member is essentially an Integer, so CStr on an enum member works the same as CStr on an integer. That is what you would expect. However, ToString has been overridden to return the more human readable version of the value. That is also what you would expect.

So, in summary:

When you want the closest string representation of the actual value of the original object, you should use CStr(). When you want the (potentially) customized, human-readable version of the value, you should use .ToString.

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

1

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.

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.

2

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.

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.

2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.