|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
ByVal vs ByRefSince using ByRef passes the memeory pointed to a variable, and ByVal
copies the variable.. Is it FASTER to use ByRef since your not causing the CPU to create a new memory allocation for the same data? If so, why would I ever want to use ByVal? Thanks Jason Roozee jroo***@gmail.com wrote:
> Since using ByRef passes the memeory pointed to a variable, and ByVal Bad logic -- faulty first premise. There's no 'since' in this, and speed is only one consideration.> copies the variable.. Is it FASTER to use ByRef since your not causing > the CPU to create a new memory allocation for the same data? > > If so, why would I ever want to use ByVal? It depends on what type of variable is being passed, and sometimes to what kind of procedure. For example, passing a long integer byref pushes the (4-byte) address of the variable onto the stack. In order to actually use the variable, the called proceduree must dereference it -- get the value from the address. So there is one push, and one dereference. Passing it byval causes vb to do the deref, and push the 4-byte value onto the stack. The called procedure need do nothing else to use the value. So here too there is one deref, and one push. In neither case is there a copy of anything made. It's neutral as far as speed goes. The difference is that a variable passed byval can't be changed by the called proc, since its location is not known, only its value. This is (almost always) a Good Thing. The same analysis holds for any scalar variable of 4 bytes or less (byte, short, single, long). For longer scalars (double, currency) it's a little bit more involved, but in real life you would have to do a whole lot of passing to see much difference -- the overhead of the call itself overwhelms the couple of cycles needed to deref another dword. Objects, arrays and UDTs are always passed byref, if only (but not only) because the size of the data tips the speed factor in favor of that. Marshalled values (those passed out of process) go though a whole different, ah, process. Strings are a different story. Passing a string ByVal to a VB procedure _does_ result in a copy, because a string is essentially a pointer, and passing it 'byval' would still leave the value unprotected. Here passing byref is clearly a winner, unless you absolutely need the protection. Passing a string to a Declared external procedure involves a conversion from Unicode to MBCS, so there is a copy of sorts, but the value is not protected because any changes made to the copy are reflected back into the original Unicode string. Byref here is a loser, since it just passes the address of the address of the copy -- for no benefit -- and 99% of external procedures couldn't deal with that anyway. There's more, but that's most of it. ....also, if you're talking to an out-of-process component then ByVal is
always best. This is because ByVal doesn't accommodate the possibility of write-back through the arguments and so the marshalling is substantially simpler. Tony Proctor "Jim Mack" <jmack@mdxi.nospam.com> wrote in message jroo***@gmail.com wrote:news:eCGeQY8ZFHA.3356@TK2MSFTNGP15.phx.gbl... > Since using ByRef passes the memeory pointed to a variable, and ByVal Bad logic -- faulty first premise. There's no 'since' in this, and speed is> copies the variable.. Is it FASTER to use ByRef since your not causing > the CPU to create a new memory allocation for the same data? > > If so, why would I ever want to use ByVal? only one consideration. It depends on what type of variable is being passed, and sometimes to what kind of procedure. For example, passing a long integer byref pushes the (4-byte) address of the variable onto the stack. In order to actually use the variable, the called proceduree must dereference it -- get the value from the address. So there is one push, and one dereference. Passing it byval causes vb to do the deref, and push the 4-byte value onto the stack. The called procedure need do nothing else to use the value. So here too there is one deref, and one push. In neither case is there a copy of anything made. It's neutral as far as speed goes. The difference is that a variable passed byval can't be changed by the called proc, since its location is not known, only its value. This is (almost always) a Good Thing. The same analysis holds for any scalar variable of 4 bytes or less (byte, short, single, long). For longer scalars (double, currency) it's a little bit more involved, but in real life you would have to do a whole lot of passing to see much difference -- the overhead of the call itself overwhelms the couple of cycles needed to deref another dword. Objects, arrays and UDTs are always passed byref, if only (but not only) because the size of the data tips the speed factor in favor of that. Marshalled values (those passed out of process) go though a whole different, ah, process. Strings are a different story. Passing a string ByVal to a VB procedure _does_ result in a copy, because a string is essentially a pointer, and passing it 'byval' would still leave the value unprotected. Here passing byref is clearly a winner, unless you absolutely need the protection. Passing a string to a Declared external procedure involves a conversion from Unicode to MBCS, so there is a copy of sorts, but the value is not protected because any changes made to the copy are reflected back into the original Unicode string. Byref here is a loser, since it just passes the address of the address of the copy -- for no benefit -- and 99% of external procedures couldn't deal with that anyway. There's more, but that's most of it. Tony Proctor wrote:
> ...also, if you're talking to an out-of-process component then ByVal Right, that's part of the "...there's more...". Also, of course, you can't literally pass out-of-process byref, since the reference has meaning only within the sending process. More, I'm sure, than the OP really wanted to know. :-)> is always best. This is because ByVal doesn't accommodate the > possibility of write-back through the arguments and so the > marshalling is substantially simpler. > > Tony Proctor -- Jim <jroo***@gmail.com> wrote in message
news:1117750094.738462.3690@g47g2000cwa.googlegroups.com... ByRef should be faster but... ByVal is handy. It'll ignore data types during > Since using ByRef passes the memeory pointed to a variable, and ByVal > copies the variable.. Is it FASTER to use ByRef since your not causing > the CPU to create a new memory allocation for the same data? > > If so, why would I ever want to use ByVal? > > Thanks > Jason Roozee compile, for one thing... ByVal is also handy if you don't want to ensure that the data you're passing won't be modified in the sub/function you're calling.... '========= Option Explicit Private Sub Test1(ByRef Arg As Long) Debug.Print Arg Arg = 1234 'modify the variable that was passed End Sub Private Sub Test2(ByVal Arg As Long) Debug.Print Arg Arg = 1234 'this ignored if ByVal End Sub Private Sub Form_Load() Dim i As Integer i = 12 Call Test1(i) 'this won't compile (wrong data type) Debug.Print i 'well... if it were the correct type, i would = 1234 Call Test2(i) 'no problem here Debug.Print i 'i still = 12 even though the sub set it to 1234 End Sub '========= -- Ken Halter - MS-MVP-VB - http://www.vbsight.com DLL Hell problems? Try ComGuard - http://www.vbsight.com/ComGuard.htm Please keep all discussions in the groups.. Jim/Ken,
Thanks for the great info. You answered exactly what I was looking for. I've always been using ByVal for all variables, and ByRef for Arrays and Objects. Except, I'll use a ByRef when I want a procedure to modify the varaible. I just wasn't sure that in the case of a string variable if it would be faster to use ByRef in all cases. Now I know. Thanks! Jason "Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.com> wrote in message For posterity: remove the "don't" when reading this.news:%23Bf7gY8ZFHA.2940@tk2msftngp13.phx.gbl... > ByVal is also handy if you don't want to ensure that the data you're > passing won't be modified in the sub/function you're calling.... "Jeff Johnson [MVP:VB]" <i.get@enough.spam> wrote in message Jeezzzzz... side-tracked mid sentence. I didn't not mean to add the "do" vs news:Ol8eZX%23ZFHA.3356@TK2MSFTNGP15.phx.gbl... > > > For posterity: remove the "don't" when reading this. Show quoteHide quote "don't" <g> -- Ken Halter - MS-MVP-VB - http://www.vbsight.com DLL Hell problems? Try ComGuard - http://www.vbsight.com/ComGuard.htm Please keep all discussions in the groups..
Code to INVERT image in VB6
simple but not clicking now Check Digits Privileges and killing a process How do you code Asynchronous MP3 playing with VB6/API? Monitoring a software installation..... Slow WMI Select Query VB6 and SPLIT Tabulating document proerties from a folder in Access Sorting a 2d array by more than 1 column |
|||||||||||||||||||||||