views:

80

answers:

1

Hello everyone!

Reading http://stackoverflow.com/questions/408101/which-is-faster-byval-or-byref made me wonder whether the comments in there did apply to Strings in terms of performance. Since strings are copied before being passed, isn't it much more efficient (if the callee doesn't need a copy of string course) to pass strings ByRef?

Thanks,
CFP.

Edit: Consider this code, which made me think there was some kind of copy going on:

Sub Main()
    Dim ByValStr As String = "Hello World (ByVal)!"
    Dim ByRefStr As String = "Hello World (ByRef)!"

    fooval(ByValStr)
    fooref(ByRefStr)

    Console.WriteLine("ByVal: " & ByValStr)
    Console.WriteLine("ByRef: " & ByRefStr)

    Console.ReadLine()
End Sub


Sub fooval(ByVal Str As String)
    Str = "foobar"
End Sub

Sub fooref(ByRef Str As String)
    Str = "foobar"
End Sub

It outputs:

ByVal: Hello World (ByVal)!
ByRef: foobar
+2  A: 

Strings are not copied before being passed. Strings are reference types, even though they behave somewhat like value types.

You should use whatever makes the most sense in the context of your requirements. (And if your requirements happen to be something like "must squeeze every last nanosecond of performance at the expense of all other considerations" then you should probably crack out the profiler rather than asking on stackoverflow!)

This is almost certainly something that you don't need to worry about, and I doubt if there's ever a significant performance difference. The only situation where I can see any chance of a difference would be when passing big value types.

LukeH
Yet if you pass `ByVal` a string `mystr` to `foobar` and in `foobar` you set `mystr = "hello"`, then the initial value of `mystr` doesn't change... So there must be some kind of copy going on, isn't there?
CFP
Strings are reference types, so you're passing *a reference* regardless of whether you use `ByVal` or `ByRef`. The difference is that when you pass `ByVal` then you're passing *a new variable containing a copy of the orginal reference*, so any changes to that variable are essentially private; when you pass `ByRef` then you're passing *the original variable*, so any changes to that variable are visible externally.
LukeH
Which means that when you pass `ByVal` and set `mystr = "hello"`, you're simply overwriting the pointer contained in the variable `mystr` to point to `"hello"`, but not changing the original pointer itself?
CFP
Well, a reference to the new string "hello" is assigned to the variable that was passed - if you passed `ByRef` then that variable is the original, external variable; if you passed `ByVal` then it's just local to the method and the original, external variable isn't affected.
LukeH
Cool, I got it now; +1 :)
CFP