|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
String Memory Recoverymemory should be recovered. ===================== However, when does the compiler recover memory for a string used in an object declaration: Set rsTemp = DaoDb.OpenRecordset("MyTBLName") or in a parameter for a called procedure? Call MyProcedure("MyTBLName") -------------------- Logic says: 1) For object declaration it would be after execution of the statement -- Set rsTemp 2) For the Called procedure it would also be after the called procedure is executed. OR would both strings be considered local to the procedure in which they reside and not be cleared until that procedures stack is popped? ---------------------- Also, is there any advantage to clearing a string in a local procedure that is used early in the procedure and not used again? David wrote:
> If a string is declared locally at the termination of the procedure It is.> string memory should be recovered. > ===================== Immediate (literal) strings used as parameters are discarded on return> However, when does the compiler recover memory for a string used in > an object declaration: > > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > or in a parameter for a called procedure? > > Call MyProcedure("MyTBLName") from the call. They're temporaries. They'll always occupy some memory, though -- the contents have to come from somewhere. > -------------------- Yes to both.> > Logic says: > > 1) For object declaration it would be after execution of the > statement -- Set rsTemp > > 2) For the Called procedure it would also be after the called > procedure is executed. > OR That would be true for declared locals strings, but not for immediate> > would both strings be considered local to the procedure in which > they reside and not be cleared until that procedures stack is > popped? strings. > ---------------------- Not unless it's huge.> > Also, is there any advantage to clearing a string in a local > procedure that is used early in the procedure and not used again? Hi David,
With OpenRecordset the name is passed in ByRef. It's unfortunate but due to the way OLE Strings work, if the argument was ByVal it would mean the value would need to be copied. That is the strings are not immutable, so passing ByVal requires the value to be copied. ByRef means that a pointer to the variable is passed in. The ByRef with OLE Strings negates the overhead of copying at the expense of encapsulation: you don't know if the method being called actually modifies the string. Your code : > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") Is the equivalent of :Dim var As String var = "MyTBLName" Set rsTemp = DaoDb.OpenRecordset(var) In that calling block the lifetime of the string is the lifetime of var, minus anything OpenRecordset might do. For example, OpenRecordset could set the variable to nothing, eg: Sub OpenRecordset(ByRef name As String) ' some code here name = vbNullString End sub If the code was like that, and you called upon it: Dim var As String var = "MyTBLName" Set rsTemp = DaoDb.OpenRecordset(var) MsgBox var You'd get an empty message box because the string has been pointed to a new string. So the lifetime is generally the calling block, but because the arguments are passed ByRef, the code being called can change the lifetime. Show quoteHide quote "David" <dw85745***@earthlink.net> wrote in message news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... > If a string is declared locally at the termination of the procedure string > memory should be recovered. > > ===================== > However, when does the compiler recover memory for a string used in an > object declaration: > > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > or in a parameter for a called procedure? > > Call MyProcedure("MyTBLName") > > -------------------- > > Logic says: > > 1) For object declaration it would be after execution of the statement -- > Set rsTemp > > 2) For the Called procedure it would also be after the called procedure is > executed. > > OR > > would both strings be considered local to the procedure in which they > reside and not be cleared until that procedures stack is popped? > > ---------------------- > > Also, is there any advantage to clearing a string in a local procedure > that is used early in the procedure and not used again? > > > > > > > > > > > > > > > > > > > Mr. Mack and Mr. McCarthy:
Both of you seem to be in agreement except for the use of the literal string passed as a parameter (Mr. Mack refers to it as an intermediate) vs. local variable declaration and assignment. Mr. McCarthy indicates the following are equivalent. ================ Your code : > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") Is the equivalent of :Dim var As String var = "MyTBLName" Set rsTemp = DaoDb.OpenRecordset(var) ==================== However, per Mr. Mack, they would not be equivalent as "var" would be retained to the end of the calling procedure, while the string "literal" parameter would be destroyed after the call. So who is right? Show quoteHide quote "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message news:eTV9Dgt8JHA.200@TK2MSFTNGP05.phx.gbl... > Hi David, > > With OpenRecordset the name is passed in ByRef. It's unfortunate but due > to the way OLE Strings work, if the argument was ByVal it would mean the > value would need to be copied. That is the strings are not immutable, so > passing ByVal requires the value to be copied. ByRef means that a pointer > to the variable is passed in. The ByRef with OLE Strings negates the > overhead of copying at the expense of encapsulation: you don't know if the > method being called actually modifies the string. > > Your code : > >> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > Is the equivalent of : > > Dim var As String > var = "MyTBLName" > Set rsTemp = DaoDb.OpenRecordset(var) > > In that calling block the lifetime of the string is the lifetime of var, > minus anything OpenRecordset might do. For example, OpenRecordset could > set the variable to nothing, eg: > > Sub OpenRecordset(ByRef name As String) > ' some code here > name = vbNullString > End sub > > If the code was like that, and you called upon it: > > Dim var As String > var = "MyTBLName" > Set rsTemp = DaoDb.OpenRecordset(var) > MsgBox var > > You'd get an empty message box because the string has been pointed to a > new string. > > So the lifetime is generally the calling block, but because the arguments > are passed ByRef, the code being called can change the lifetime. > > > > > > > > > > "David" <dw85745***@earthlink.net> wrote in message > news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... >> If a string is declared locally at the termination of the procedure >> string memory should be recovered. >> >> ===================== >> However, when does the compiler recover memory for a string used in an >> object declaration: >> >> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") >> >> or in a parameter for a called procedure? >> >> Call MyProcedure("MyTBLName") >> >> -------------------- >> >> Logic says: >> >> 1) For object declaration it would be after execution of the >> statement -- Set rsTemp >> >> 2) For the Called procedure it would also be after the called procedure >> is executed. >> >> OR >> >> would both strings be considered local to the procedure in which they >> reside and not be cleared until that procedures stack is popped? >> >> ---------------------- >> >> Also, is there any advantage to clearing a string in a local procedure >> that is used early in the procedure and not used again? >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >
Show quote
Hide quote
"David" <dw85745***@earthlink.net> wrote in message Neithernews:unXIgSz8JHA.4976@TK2MSFTNGP04.phx.gbl... > Mr. Mack and Mr. McCarthy: > > Both of you seem to be in agreement except for the use of the literal string > passed as a parameter (Mr. Mack refers to it as an intermediate) vs. local > variable declaration and assignment. Mr. McCarthy indicates the following > are equivalent. > > ================ > Your code : > > > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > Is the equivalent of : > > Dim var As String > var = "MyTBLName" > Set rsTemp = DaoDb.OpenRecordset(var) > > ==================== > > However, per Mr. Mack, they would not be equivalent as "var" would be > retained to the end of the calling procedure, while the string "literal" > parameter would be destroyed after the call. > > So who is right? > David wrote:
> Mr. Mack and Mr. McCarthy: FWIW I called it an 'immediate', not an 'intermediate'. Just another> > Both of you seem to be in agreement except for the use of the > literal string passed as a parameter (Mr. Mack refers to it as an > intermediate) vs. local variable declaration and assignment. Mr. > McCarthy indicates the following are equivalent. way of saying 'literal'. Show quoteHide quote > ================ Functionally, we both are.> Your code : > >> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > Is the equivalent of : > > Dim var As String > var = "MyTBLName" > Set rsTemp = DaoDb.OpenRecordset(var) > > ==================== > > However, per Mr. Mack, they would not be equivalent as "var" would > be retained to the end of the calling procedure, while the string > "literal" parameter would be destroyed after the call. > > So who is right? What McCarthy shows is the logical equivalent, not necessarily the physical equivalent. The missing step is an implied "var = vbNullString" following the call. There must be a BSTR temporary created to pass into the function, and its contents must come from somewhere. The 'somewhere' in this case is the program memory occupied by the literal. That memory, the literal string, never goes away while your program is running. But the BSTR created for the call is released as soon as the function returns. There's still a 4-byte descriptor on the stack, just as if you had said 'Dim var As String', but it's a null pointer. So the string descriptor lives on the stack and will go away as part of leaving the local function, but the contents it pointed to are gone by that point. Except, of course, for the literal, which has program scope and life -- nothing you can do about that. Hi David,
Are you asking whether or not : Sub Foo Set rsTemp = DaoDb.OpenRecordset("MyTBLName") '(a) released here ' more code '(b) released here End Sub ? If so I make no claim as to either. It'd be hard to test other than looking at the registers as this is the kind of thing an optimizing compiler should be able to decide on. The string literal is initialized as an OLE String probably using SysAllocStringLen. Inside Foo a call to SysFreeString will also be made on that variable. Whether or not that variable still points to the same string depends on the code in the method being called.; it is however unlikely OpenRecordset would modify the string, but in other code it is something to be wary of. Whether SysFreeString is called at (a) or (b), I'm not sure. It's rare that would matter. If it did, you could ensure it is by coding it as: Dim var As String var = "MyTBLName" Set rsTemp = DaoDb.OpenRecordset(var) var = vbNullString Show quoteHide quote "David" <dw85745***@earthlink.net> wrote in message news:unXIgSz8JHA.4976@TK2MSFTNGP04.phx.gbl... > Mr. Mack and Mr. McCarthy: > > Both of you seem to be in agreement except for the use of the literal > string passed as a parameter (Mr. Mack refers to it as an intermediate) > vs. local variable declaration and assignment. Mr. McCarthy indicates the > following are equivalent. > > ================ > Your code : > >> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > Is the equivalent of : > > Dim var As String > var = "MyTBLName" > Set rsTemp = DaoDb.OpenRecordset(var) > > ==================== > > However, per Mr. Mack, they would not be equivalent as "var" would be > retained to the end of the calling procedure, while the string "literal" > parameter would be destroyed after the call. > > So who is right? > > > > > "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message > news:eTV9Dgt8JHA.200@TK2MSFTNGP05.phx.gbl... >> Hi David, >> >> With OpenRecordset the name is passed in ByRef. It's unfortunate but due >> to the way OLE Strings work, if the argument was ByVal it would mean the >> value would need to be copied. That is the strings are not immutable, so >> passing ByVal requires the value to be copied. ByRef means that a pointer >> to the variable is passed in. The ByRef with OLE Strings negates the >> overhead of copying at the expense of encapsulation: you don't know if >> the method being called actually modifies the string. >> >> Your code : >> >>> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") >> >> Is the equivalent of : >> >> Dim var As String >> var = "MyTBLName" >> Set rsTemp = DaoDb.OpenRecordset(var) >> >> In that calling block the lifetime of the string is the lifetime of var, >> minus anything OpenRecordset might do. For example, OpenRecordset could >> set the variable to nothing, eg: >> >> Sub OpenRecordset(ByRef name As String) >> ' some code here >> name = vbNullString >> End sub >> >> If the code was like that, and you called upon it: >> >> Dim var As String >> var = "MyTBLName" >> Set rsTemp = DaoDb.OpenRecordset(var) >> MsgBox var >> >> You'd get an empty message box because the string has been pointed to a >> new string. >> >> So the lifetime is generally the calling block, but because the arguments >> are passed ByRef, the code being called can change the lifetime. >> >> >> >> >> >> >> >> >> >> "David" <dw85745***@earthlink.net> wrote in message >> news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... >>> If a string is declared locally at the termination of the procedure >>> string memory should be recovered. >>> >>> ===================== >>> However, when does the compiler recover memory for a string used in an >>> object declaration: >>> >>> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") >>> >>> or in a parameter for a called procedure? >>> >>> Call MyProcedure("MyTBLName") >>> >>> -------------------- >>> >>> Logic says: >>> >>> 1) For object declaration it would be after execution of the >>> statement -- Set rsTemp >>> >>> 2) For the Called procedure it would also be after the called procedure >>> is executed. >>> >>> OR >>> >>> would both strings be considered local to the procedure in which they >>> reside and not be cleared until that procedures stack is popped? >>> >>> ---------------------- >>> >>> Also, is there any advantage to clearing a string in a local procedure >>> that is used early in the procedure and not used again? >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >> > > > What difference does it make? Are you planning> Both of you seem to be in agreement except for the use of the literal string > passed as a parameter ..... > However, per Mr. Mack, they would not be equivalent as "var" would be > retained to the end of the calling procedure, while the string "literal" > parameter would be destroyed after the call. > > So who is right? > to pass 2 MB literal strings? It's interesting how the most nitpicking technical questions never fail to elicit the most interest. :) While I defer to Jim Mack and Ralph in terms of expertise with this, I think there's also another aspect to your angels-on-the-head-of-a-pin count: Matthew Curland, in his VB book, demonstrates the inefficiency of repeated string concatenation. In the course of that discussion he points out that there's a 64 KB "string cache" that "essentially guarantees that you can't mess up too badly with small strings, no matter how bad the code is." Which is to say that even if it mattered whether you reclaimed the memory from your 20-odd byte string, it still really doesn't. On Mon, 22 Jun 2009 11:12:05 +1000, "Bill McCarthy" <TPASoft.com Are
Identity Thieves> wrote: >With OpenRecordset the name is passed in ByRef. I doubt that.Here is the IDL definition for the OpenRecordset method (DAO 3.6): [id(0x60030027), helpcontext(0x0010110b)] HRESULT OpenRecordset( [in] BSTR Name, [in, optional] VARIANT Type, [in, optional] VARIANT Options, [in, optional] VARIANT LockEdit, [out, retval] Recordset** pprst); IMHO that says clearly that the Name parameter is passed ByVal. If it was passed ByRef, it would look like this: [in, out] BSTR* Name If I'm wrong, just let me know. If not, just do likewise, without another 20+ posts party. *g* "Wolfgang Enzinger" <usenet200***@temporaryforwarding.com> wrote in message Strange, here it shows in object browser as if ByRef. It would make more news:8msv35t4t8i2f98hpu0vuemrkiqrn4tott@4ax.com... > On Mon, 22 Jun 2009 11:12:05 +1000, "Bill McCarthy" <TPASoft.com Are > Identity Thieves> wrote: > >>With OpenRecordset the name is passed in ByRef. > > I doubt that. > sense for it to be ByVal. Perhaps this is a limitation of the VB Object browser and external libraries. It does show the ByVal for one's own code. Show quoteHide quote > Here is the IDL definition for the OpenRecordset method (DAO 3.6): > > [id(0x60030027), helpcontext(0x0010110b)] > HRESULT OpenRecordset( > [in] BSTR Name, > [in, optional] VARIANT Type, > [in, optional] VARIANT Options, > [in, optional] VARIANT LockEdit, > [out, retval] Recordset** pprst); > > IMHO that says clearly that the Name parameter is passed ByVal. If it > was passed ByRef, it would look like this: > > [in, out] BSTR* Name > > If I'm wrong, just let me know. If not, just do likewise, without > another 20+ posts party. *g*
Show quote
Hide quote
"David" <dw85745***@earthlink.net> wrote in message ha, Well here is my two cents ...news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... > If a string is declared locally at the termination of the procedure string > memory should be recovered. > > ===================== > However, when does the compiler recover memory for a string used in an > object declaration: > > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > or in a parameter for a called procedure? > > Call MyProcedure("MyTBLName") > > -------------------- > > Logic says: > > 1) For object declaration it would be after execution of the statement -- > Set rsTemp > > 2) For the Called procedure it would also be after the called procedure is > executed. > > OR > > would both strings be considered local to the procedure in which they reside > and not be cleared until that procedures stack is popped? > > ---------------------- > > Also, is there any advantage to clearing a string in a local procedure that > is used early in the procedure and not used again? > In the examples given , using VB*, no "string memory" would ever be 'cleared' or 'recovered', as no "string-memory" would ever be created. Because you are using literal string constants. These strings are stored in the string section of the programs data segment. During development the name or identifier for these strings is the string itself and it evaluates to an address in the Data section. So in all your examples, you would be passing the address of a 'hard-coded' block of memory. Each of the procedures would be using only the Data section address for these strings. Also note that OLE marshalling is not involved as it appears you are using DAO for your object example. DAO runs inproc. hth -ralph [VB* this assumes you are using the classic VB COM-based development platform(VB6 or lower)] Hi Ralph,
but surely the code being called is expecting an OLE BSTR ByRef. and as such could change the string reference. What does VB6 do there ? Let's say the code being called is : Sub Bar(ByRef x as String) x = "baz" ' more code End Sub Wouldn't VB have to call SysFreeStr when the new value is assigned to x ?? Show quoteHide quote "Ralph" <nt_consultin***@yahoo.com> wrote in message news:%23OMI8az8JHA.3544@TK2MSFTNGP04.phx.gbl... > > "David" <dw85745***@earthlink.net> wrote in message > news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... >> If a string is declared locally at the termination of the procedure >> string >> memory should be recovered. >> >> ===================== >> However, when does the compiler recover memory for a string used in an >> object declaration: >> >> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") >> >> or in a parameter for a called procedure? >> >> Call MyProcedure("MyTBLName") >> >> -------------------- >> >> Logic says: >> >> 1) For object declaration it would be after execution of the >> statement -- >> Set rsTemp >> >> 2) For the Called procedure it would also be after the called procedure >> is >> executed. >> >> OR >> >> would both strings be considered local to the procedure in which they > reside >> and not be cleared until that procedures stack is popped? >> >> ---------------------- >> >> Also, is there any advantage to clearing a string in a local procedure > that >> is used early in the procedure and not used again? >> > > ha, Well here is my two cents ... > > In the examples given , using VB*, no "string memory" would ever be > 'cleared' or 'recovered', as no "string-memory" would ever be created. > Because you are using literal string constants. These strings are stored > in > the string section of the programs data segment. > > During development the name or identifier for these strings is the string > itself and it evaluates to an address in the Data section. So in all your > examples, you would be passing the address of a 'hard-coded' block of > memory. > > Each of the procedures would be using only the Data section address for > these strings. > > Also note that OLE marshalling is not involved as it appears you are using > DAO for your object example. DAO runs inproc. > > hth > -ralph > > [VB* this assumes you are using the classic VB COM-based development > platform(VB6 or lower)] > >
Show quote
Hide quote
"Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message No.news:uVt39jz8JHA.4976@TK2MSFTNGP04.phx.gbl... > Hi Ralph, > > but surely the code being called is expecting an OLE BSTR ByRef. and as such > could change the string reference. What does VB6 do there ? Let's say the > code being called is : > > Sub Bar(ByRef x as String) > x = "baz" > ' more code > End Sub > > Wouldn't VB have to call SysFreeStr when the new value is assigned to x ?? > This is a point of common confusion with the classic VB development platform. We often say it is "COM-based", and it is. It's objects (Classes, Forms, and Controls) follow COM protocol. It's datatypes are suspiciously OLE datatypes (not really that strange when you consider VB support was behind the design, if not the original emphasis, of OLE. But, COM is only a specification. It's implementation (well MS's implementation) is by OLE. OLE itself is both a specification and an implementation. Thus VB's inherent and created objects behave and act identical (or rather damn close) to ActiveX objects. Most analogies fit. That's the beauty of a common object model. But the internal implementation is very different. Unfortunately the VB Runtime is proprietorial and essentially hidden. We can make good guesses as to what it's doing, but hard proof is hard to come by. In your example, within VB, "x" is merely an auto variable on the stack containing a pointer to a block of memory in the Data string section. -ralph hi Ralph,
> In your example, within VB, "x" is merely an auto variable on the stack I don't think so. Take my example> containing a pointer to a block of memory in the Data string section. > >> Sub Bar(ByRef x as String) inside the method Bar, there is no way for the compiler to know if a literal >> x = "baz" >> ' more code >> End Sub is passed in or not. As it is a reference to a string. SysFreeString *must* be called to release the string. I think if you also check VarPtr, StrPtr or call Len on the string you will see it not only is, but must be an OLE BSTR. Also, if it was just a pointer to the string table, then Mid(x,1) = "a" etc, would modify the string table My guess is VB loads it's string table, but creates OLE strings and copies the data into them. Show quoteHide quote "Ralph" <nt_consultin***@yahoo.com> wrote in message news:%23gC2MK08JHA.3916@TK2MSFTNGP02.phx.gbl... > > "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message > news:uVt39jz8JHA.4976@TK2MSFTNGP04.phx.gbl... >> Hi Ralph, >> >> but surely the code being called is expecting an OLE BSTR ByRef. and as > such >> could change the string reference. What does VB6 do there ? Let's say >> the >> code being called is : >> >> Sub Bar(ByRef x as String) >> x = "baz" >> ' more code >> End Sub >> >> Wouldn't VB have to call SysFreeStr when the new value is assigned to x >> ?? >> > > No. > > This is a point of common confusion with the classic VB development > platform. We often say it is "COM-based", and it is. It's objects > (Classes, > Forms, and Controls) follow COM protocol. It's datatypes are suspiciously > OLE datatypes (not really that strange when you consider VB support was > behind the design, if not the original emphasis, of OLE. But, COM is only > a > specification. It's implementation (well MS's implementation) is by OLE. > OLE > itself is both a specification and an implementation. > > Thus VB's inherent and created objects behave and act identical (or rather > damn close) to ActiveX objects. Most analogies fit. That's the beauty of a > common object model. But the internal implementation is very different. > > Unfortunately the VB Runtime is proprietorial and essentially hidden. We > can > make good guesses as to what it's doing, but hard proof is hard to come > by. > > In your example, within VB, "x" is merely an auto variable on the stack > containing a pointer to a block of memory in the Data string section. > > -ralph > > >
Show quote
Hide quote
"Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message Sorry, but that's not how it works for internal objects, and your guess isnews:efdlkR08JHA.2604@TK2MSFTNGP05.phx.gbl... > hi Ralph, > > > In your example, within VB, "x" is merely an auto variable on the stack > > containing a pointer to a block of memory in the Data string section. > > > > I don't think so. Take my example > > >> Sub Bar(ByRef x as String) > >> x = "baz" > >> ' more code > >> End Sub > > inside the method Bar, there is no way for the compiler to know if a literal > is passed in or not. As it is a reference to a string. SysFreeString *must* > be called to release the string. I think if you also check VarPtr, StrPtr > or call Len on the string you will see it not only is, but must be an OLE > BSTR. Also, if it was just a pointer to the string table, then Mid(x,1) = > "a" etc, would modify the string table > My guess is VB loads it's string table, but creates OLE strings and copies > the data into them. > essentially wrong on a global scale, with the proviso that the Data string section is read-only, ie, r-value only, no l-value, and in VB - Strings are objects. So yes, whenever you "touch" them you often get a "thing". Why? Because you asked for one. Duh. And again don't be so surprised to discover VB Strings are OLE Bstrs. Where do you think "OLE Bstrs" came from? -ralph Hi Ralph,
Show quoteHide quote "Ralph" <nt_consultin***@yahoo.com> wrote in message You've got me lost there. r-value only and l-value is a compile time thing. news:uMVp4t08JHA.1340@TK2MSFTNGP05.phx.gbl... > > "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message > news:efdlkR08JHA.2604@TK2MSFTNGP05.phx.gbl... >> hi Ralph, >> >> > In your example, within VB, "x" is merely an auto variable on the stack >> > containing a pointer to a block of memory in the Data string section. >> > >> >> I don't think so. Take my example >> >> >> Sub Bar(ByRef x as String) >> >> x = "baz" >> >> ' more code >> >> End Sub >> >> inside the method Bar, there is no way for the compiler to know if a > literal >> is passed in or not. As it is a reference to a string. SysFreeString > *must* >> be called to release the string. I think if you also check VarPtr, > StrPtr >> or call Len on the string you will see it not only is, but must be an OLE >> BSTR. Also, if it was just a pointer to the string table, then Mid(x,1) = >> "a" etc, would modify the string table >> My guess is VB loads it's string table, but creates OLE strings and >> copies >> the data into them. >> > > Sorry, but that's not how it works for internal objects, and your guess is > essentially wrong on a global scale, with the proviso that the Data string > section is read-only, ie, r-value only, no l-value, Obviously string tables you'd want read only, but there is no magic protection that silently swallows any attempts to write there. Code that re-assigns the ByRef variable or modifies the string, or calls Len, StrPtr, VarPtr etc, cannot be on a pointer to the string table treated as r-values only. > and in VB - Strings are They are "touched" by being defined as a parameter beign passed into a > objects. So yes, whenever you "touch" them you often get a "thing". Why? > Because you asked for one. Duh. > function. > And again don't be so surprised to discover VB Strings are OLE Bstrs. I don't get what you are referring to here. I said they are OLE BSTR's, > Where > do you think "OLE Bstrs" came from? > been saying that for over a decade now so it's no surprise to me. I think you are badly mistaken if you think OLE BSTRs are not passed to methods that declare there parameters as such. The only thing I can think of is perhaps you are confusing the use of string literals in VB's own internal string manipulation inside a method, such as if you wrote "abc" & "def". But passed as a parameter the contract must be met, and that means using an OLE string, and that by definition precludes a pointer direct to the string constant's table. I'm a little over my head here hence my question.
But from my simplistic assessment logic says: 1) The literal in each procedure in included in the string table and remains their (in the table) throughout program execution. 2) During compilation a pointer is assigned to get to each string in the order in which it is needed 3) Whether the string is used as a calling parameter or assigned and/or reassigned in the local procedure, the pointers to the string are pushed on the stack and not removed until the procedure ends when the stack is cleared (popped). To do otherwise seems very inefficient as: 1) the pointer takes up little space, and 2) to go down through the stack to find it (the pointer), remove it, and then recreate the stack seems a lot of work Show quoteHide quote "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message news:uVt39jz8JHA.4976@TK2MSFTNGP04.phx.gbl... > Hi Ralph, > > but surely the code being called is expecting an OLE BSTR ByRef. and as > such could change the string reference. What does VB6 do there ? Let's > say the code being called is : > > Sub Bar(ByRef x as String) > x = "baz" > ' more code > End Sub > > Wouldn't VB have to call SysFreeStr when the new value is assigned to x ?? > > > > > > > > "Ralph" <nt_consultin***@yahoo.com> wrote in message > news:%23OMI8az8JHA.3544@TK2MSFTNGP04.phx.gbl... >> >> "David" <dw85745***@earthlink.net> wrote in message >> news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... >>> If a string is declared locally at the termination of the procedure >>> string >>> memory should be recovered. >>> >>> ===================== >>> However, when does the compiler recover memory for a string used in an >>> object declaration: >>> >>> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") >>> >>> or in a parameter for a called procedure? >>> >>> Call MyProcedure("MyTBLName") >>> >>> -------------------- >>> >>> Logic says: >>> >>> 1) For object declaration it would be after execution of the >>> statement -- >>> Set rsTemp >>> >>> 2) For the Called procedure it would also be after the called procedure >>> is >>> executed. >>> >>> OR >>> >>> would both strings be considered local to the procedure in which they >> reside >>> and not be cleared until that procedures stack is popped? >>> >>> ---------------------- >>> >>> Also, is there any advantage to clearing a string in a local procedure >> that >>> is used early in the procedure and not used again? >>> >> >> ha, Well here is my two cents ... >> >> In the examples given , using VB*, no "string memory" would ever be >> 'cleared' or 'recovered', as no "string-memory" would ever be created. >> Because you are using literal string constants. These strings are stored >> in >> the string section of the programs data segment. >> >> During development the name or identifier for these strings is the string >> itself and it evaluates to an address in the Data section. So in all your >> examples, you would be passing the address of a 'hard-coded' block of >> memory. >> >> Each of the procedures would be using only the Data section address for >> these strings. >> >> Also note that OLE marshalling is not involved as it appears you are >> using >> DAO for your object example. DAO runs inproc. >> >> hth >> -ralph >> >> [VB* this assumes you are using the classic VB COM-based development >> platform(VB6 or lower)] >> >> > Hi David,
The method being called, especially if it is an external library written in possibly a different language, expects an OLE BSTR ByRef. That must have the in memory structure of an OLE BSTR which means it contains a value that points to the start of the string, and the four bytes prior to that indicate the length of the string. VB may load it's string tables as such, but there are still other issues. Consider this code : Sub Foo(ByRef x As String) MsgBox x Mid(x, 1, 1) = "a" End Sub If you called that such as : Foo "zzz" The second time you called that, it should display "azz" if in fact a pointer to the string table was passed in. Remember the code being called upon, Foo in this case, can't know before hand whether a literal or a variable is passed into it. Show quoteHide quote "David" <dw85745***@earthlink.net> wrote in message news:O3coHJ08JHA.3544@TK2MSFTNGP04.phx.gbl... > I'm a little over my head here hence my question. > > But from my simplistic assessment logic says: > > 1) The literal in each procedure in included in the string table and > remains their (in the table) throughout program execution. > 2) During compilation a pointer is assigned to get to each string > in the order in which it is needed > 3) Whether the string is used as a calling parameter > or assigned and/or reassigned in the local procedure, the pointers to the > string are pushed on the stack and not removed until the procedure ends > when the stack is cleared (popped). > > To do otherwise seems very inefficient as: > 1) the pointer takes up little space, and > 2) to go down through the stack to find it (the pointer), remove it, and > then recreate the stack seems a lot of work > > > > "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message > news:uVt39jz8JHA.4976@TK2MSFTNGP04.phx.gbl... >> Hi Ralph, >> >> but surely the code being called is expecting an OLE BSTR ByRef. and as >> such could change the string reference. What does VB6 do there ? Let's >> say the code being called is : >> >> Sub Bar(ByRef x as String) >> x = "baz" >> ' more code >> End Sub >> >> Wouldn't VB have to call SysFreeStr when the new value is assigned to x >> ?? >> >> >> >> >> >> >> >> "Ralph" <nt_consultin***@yahoo.com> wrote in message >> news:%23OMI8az8JHA.3544@TK2MSFTNGP04.phx.gbl... >>> >>> "David" <dw85745***@earthlink.net> wrote in message >>> news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... >>>> If a string is declared locally at the termination of the procedure >>>> string >>>> memory should be recovered. >>>> >>>> ===================== >>>> However, when does the compiler recover memory for a string used in an >>>> object declaration: >>>> >>>> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") >>>> >>>> or in a parameter for a called procedure? >>>> >>>> Call MyProcedure("MyTBLName") >>>> >>>> -------------------- >>>> >>>> Logic says: >>>> >>>> 1) For object declaration it would be after execution of the >>>> statement -- >>>> Set rsTemp >>>> >>>> 2) For the Called procedure it would also be after the called procedure >>>> is >>>> executed. >>>> >>>> OR >>>> >>>> would both strings be considered local to the procedure in which they >>> reside >>>> and not be cleared until that procedures stack is popped? >>>> >>>> ---------------------- >>>> >>>> Also, is there any advantage to clearing a string in a local procedure >>> that >>>> is used early in the procedure and not used again? >>>> >>> >>> ha, Well here is my two cents ... >>> >>> In the examples given , using VB*, no "string memory" would ever be >>> 'cleared' or 'recovered', as no "string-memory" would ever be created. >>> Because you are using literal string constants. These strings are stored >>> in >>> the string section of the programs data segment. >>> >>> During development the name or identifier for these strings is the >>> string >>> itself and it evaluates to an address in the Data section. So in all >>> your >>> examples, you would be passing the address of a 'hard-coded' block of >>> memory. >>> >>> Each of the procedures would be using only the Data section address for >>> these strings. >>> >>> Also note that OLE marshalling is not involved as it appears you are >>> using >>> DAO for your object example. DAO runs inproc. >>> >>> hth >>> -ralph >>> >>> [VB* this assumes you are using the classic VB COM-based development >>> platform(VB6 or lower)] >>> >>> >> > >
Show quote
Hide quote
"Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message If the OP had asked about calling an ActiveX component, then your commentsnews:uqei4V08JHA.5704@TK2MSFTNGP03.phx.gbl... > Hi David, > > The method being called, especially if it is an external library written in > possibly a different language, expects an OLE BSTR ByRef. That must have > the in memory structure of an OLE BSTR which means it contains a value that > points to the start of the string, and the four bytes prior to that indicate > the length of the string. VB may load it's string tables as such, but there > are still other issues. Consider this code : > > Sub Foo(ByRef x As String) > MsgBox x > Mid(x, 1, 1) = "a" > End Sub > > If you called that such as : > > Foo "zzz" > > The second time you called that, it should display "azz" if in fact a > pointer to the string table was passed in. Remember the code being called > upon, Foo in this case, can't know before hand whether a literal or a > variable is passed into it. > might have some relevancy, but he didn't and they aren't. -ralph Hi Ralph,
Show quoteHide quote "Ralph" <nt_consultin***@yahoo.com> wrote in message I think the DAO code he showed was in fact an external library, but the case news:O2km$u08JHA.5064@TK2MSFTNGP03.phx.gbl... > > "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message > news:uqei4V08JHA.5704@TK2MSFTNGP03.phx.gbl... >> Hi David, >> >> The method being called, especially if it is an external library written > in >> possibly a different language, expects an OLE BSTR ByRef. That must have >> the in memory structure of an OLE BSTR which means it contains a value > that >> points to the start of the string, and the four bytes prior to that > indicate >> the length of the string. VB may load it's string tables as such, but > there >> are still other issues. Consider this code : >> >> Sub Foo(ByRef x As String) >> MsgBox x >> Mid(x, 1, 1) = "a" >> End Sub >> >> If you called that such as : >> >> Foo "zzz" >> >> The second time you called that, it should display "azz" if in fact a >> pointer to the string table was passed in. Remember the code being called >> upon, Foo in this case, can't know before hand whether a literal or a >> variable is passed into it. >> > > If the OP had asked about calling an ActiveX component, then your comments > might have some relevancy, but he didn't and they aren't. > is the same with internal methods. If you have the method Foo as above, and call it with a literal and also with a variable, the compiler cannot optimize that out, it has to respect the OLE BSTR contract.
Show quote
Hide quote
"David" <dw85745***@earthlink.net> wrote in message Basically correct except for this statement:news:O3coHJ08JHA.3544@TK2MSFTNGP04.phx.gbl... > I'm a little over my head here hence my question. > > But from my simplistic assessment logic says: > > 1) The literal in each procedure in included in the string table and > remains their (in the table) throughout program execution. > 2) During compilation a pointer is assigned to get to each string > in the order in which it is needed > 3) Whether the string is used as a calling parameter > or assigned and/or reassigned in the local procedure, the pointers to the > string are pushed on the stack and not removed until the procedure ends when > the stack is cleared (popped). > > To do otherwise seems very inefficient as: > 1) the pointer takes up little space, and > 2) to go down through the stack to find it (the pointer), remove it, and > then recreate the stack seems a lot of work > "During compilation a pointer is assigned to get to each string in the order in which it is needed" Note: there are two different environments one needs to consider when taking about 'classic' VB. 1) There is the design-time VBIDE where all code is parsed and converted to pcode during development. [Note: And this is particularly important (not so much in this context, but useful to keep in mind whenever you delve into VB "internals" <smile>, ie, likely to come up later), the 'text' you see displayed in the VBEditor is purely an artifact. Consider it as the parser'sway of providing an interactive interface to the programmer.] So at design-time whenever a literal string constant is used it is place in an internal cache/table and the literal string is replaced in pcode with a lookup into that table. (It appears to be a combined token, something like <table>.<offset>.) How many of these tables and where they are located depends on 'scope'. Const values are stored in their own tables, again by "scope". In actual use temp vars may or may not be created depending on context. 2) At compile-time, whether pcode or native, these string tables are bundled up and placed in a Data string section. And the lookups are replace with an address into that data section. Note: When compiling native code with string optimization on, this section is further analyzed for duplicates. Duplicates are removed and all locations that use the same string receive the same address. On occasion within a procedure the VB parser seems to do a bit of string optimization itself. The eventual order in the Data String section probably corresponds with the order they appeared in the translating units as they compile, but I wouldn't count on it. -ralph Ralph wrote:
Show quoteHide quote > In an ideal world, yes. But not in VB-land.> ha, Well here is my two cents ... > > In the examples given , using VB*, no "string memory" would ever be > 'cleared' or 'recovered', as no "string-memory" would ever be > created. Because you are using literal string constants. These > strings are stored in the string section of the programs data > segment. > > During development the name or identifier for these strings is the > string itself and it evaluates to an address in the Data section. > So in all your examples, you would be passing the address of a > 'hard-coded' block of memory. > > Each of the procedures would be using only the Data section address > for these strings. As a writer of DLLs called by VB, both TLB-based and Declared, I've been on both ends of such calls. In every case, VB creates a temporary BSTR, passes it to the function, and destroys it on return. The external function cannot know whether the contents of the BSTR came from a static string, a computed string, a literal, or whatever. In every case it sees a BSTR (in the case of Declared functions, an Ansi BSTR which is one step removed from the original). What you describe is possible, given a contract that calls for it, but in VB no such contract is ever negotiated. Even in cases where the external function expects a LPSZ, VB will pass a BSTR that mimics one. Every time.
Show quote
Hide quote
"Jim Mack" <jmack@mdxi.nospam.com> wrote in message If the OP had asked about calling an external regular dll, then yournews:%23nvTpb08JHA.2120@TK2MSFTNGP02.phx.gbl... > Ralph wrote: > > > > ha, Well here is my two cents ... > > > > In the examples given , using VB*, no "string memory" would ever be > > 'cleared' or 'recovered', as no "string-memory" would ever be > > created. Because you are using literal string constants. These > > strings are stored in the string section of the programs data > > segment. > > > > During development the name or identifier for these strings is the > > string itself and it evaluates to an address in the Data section. > > So in all your examples, you would be passing the address of a > > 'hard-coded' block of memory. > > > > Each of the procedures would be using only the Data section address > > for these strings. > > In an ideal world, yes. But not in VB-land. > > As a writer of DLLs called by VB, both TLB-based and Declared, I've > been on both ends of such calls. In every case, VB creates a temporary > BSTR, passes it to the function, and destroys it on return. The > external function cannot know whether the contents of the BSTR came > from a static string, a computed string, a literal, or whatever. In > every case it sees a BSTR (in the case of Declared functions, an Ansi > BSTR which is one step removed from the original). > > What you describe is possible, given a contract that calls for it, but > in VB no such contract is ever negotiated. Even in cases where the > external function expects a LPSZ, VB will pass a BSTR that mimics one. > Every time. > comments would have some relevancy, but he didn't and they aren't. -ralph Ralph wrote:
> Which of these OP scenarios are you referring to?> If the OP had asked about calling an external regular dll, then your > comments would have some relevancy, but he didn't and they aren't. Set rsTemp = DaoDb.OpenRecordset("MyTBLName") Call MyProcedure("MyTBLName") The first clearly makes reference to something external and will follow the path I set out. I haven't examined the compiler output for the second, so I can't speak about with direct experience. The best you can say is that it depends on the prototype for MyProcedure. If it's expecting a Variant, for example, or a String by reference, then VB has no choice but to create a BSTR using the contents of the literal. If it's expecting a String by value, then it will still create a BSTR because for internal procedures, "ByVal As String" has a different meaning than it does for external procedures. Internally, VB will create a copy of the string to protect its value. So in each case you can infer that a BSTR will be created and passed. -- Jim
Show quote
Hide quote
"Jim Mack" <jmack@mdxi.nospam.com> wrote in message There is no evidence that "DaoDb" is an external object. It could be a VBnews:OoOvVX18JHA.5704@TK2MSFTNGP03.phx.gbl... > Ralph wrote: > > > > If the OP had asked about calling an external regular dll, then your > > comments would have some relevancy, but he didn't and they aren't. > > Which of these OP scenarios are you referring to? > > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > Call MyProcedure("MyTBLName") > > The first clearly makes reference to something external and will > follow the path I set out. > Class. If it is in fact a DAO access library object, then their is little difference, since the object is created in the application space just as though it was a VB Class. (Don't confuse DAO with ADO - they are to very different implementations, though share a similar interface.) > I haven't examined the compiler output for the second, so I can't Not necessarily. The OP used literal string constants in his examples. They> speak about with direct experience. The best you can say is that it > depends on the prototype for MyProcedure. If it's expecting a Variant, > for example, or a String by reference, then VB has no choice but to > create a BSTR using the contents of the literal. > > If it's expecting a String by value, then it will still create a BSTR > because for internal procedures, "ByVal As String" has a different > meaning than it does for external procedures. Internally, VB will > create a copy of the string to protect its value. > > So in each case you can infer that a BSTR will be created and passed. > are not objects - they are simply pointers to a Data string section. The OP's question was when is this "string memory" recovered? The simple answer is never - it was never allocated in the first place. You are correct that generally you can "infer" that eventually the called procedure may construct an object and thus allocate memory for its construction, but then maybe not. Depends on what one asks VB to do. But in any case the called procedure takes on all responsibility. There was no "string memory" going in, and hopefully there will be no lingering "string memory" when it returns. lol -ralph Ralph wrote:
Show quoteHide quote > Jim Mack wrote... No matter what it is, you have to examine this from the perspective of>> >> Which of these OP scenarios are you referring to? >> >> Set rsTemp = DaoDb.OpenRecordset("MyTBLName") >> >> Call MyProcedure("MyTBLName") >> >> The first clearly makes reference to something external and will >> follow the path I set out. > > There is no evidence that "DaoDb" is an external object. It could > be a VB Class. If it is in fact a DAO access library object, then > their is little difference, since the object is created in the > application space just as though it was a VB Class. (Don't confuse > DAO with ADO - they are to very different implementations, though > share a similar interface.) the called procedure and what contract it has with VB. The called proc must be able to accept strings from VB, no matter where they come from. They could be temporaries, variant-contained, locals, literals, globals, whatever. So there must be a consistent, contracted way of passing these in. Unless you're saying that the called proc can change its behavior and its interface when called with a literal string as an argument, I think you have to agree that what arrives at the callee is the same in all cases. And that must be a BSTR if anything input could be a BSTR (and we know it can). >> ... Here I can only repeat the above. If the callee CAN accept a BSTR,>> >> So in each case you can infer that a BSTR will be created and >> passed. >> > > Not necessarily. The OP used literal string constants in his > examples. They are not objects - they are simply pointers to a Data > string section. The OP's question was when is this "string memory" > recovered? The simple answer is never - it was never allocated in > the first place. then it MUST be passed one, by contract. I would love to hear how the callee, which is opaque to the caller, can alter its behavior to accept a simple pointer when it expects a BSTR. > ... But in any case the called procedure takes on all Including publishing an interface that the caller must honor.> responsibility. > There was no "string memory" going in, and I completely disagree, and I have yet to hear the basis for this> hopefully there will be no lingering "string memory" when it > returns. lol claim. Yes, the data can be traced back to a stringtable. But a stringtable does not contain BSTR, which is what must be passed to an arbitrary callee. It must be copied to one for passing. Gawd, this sounds like a discussion in a C group. (-: -- Jim
Show quote
Hide quote
"Jim Mack" <jmack@mdxi.nospam.com> wrote in message It does. And it would likely take a decent grounding in C/Coff/... tonews:%23M2qzP28JHA.3916@TK2MSFTNGP02.phx.gbl... > > Here I can only repeat the above. If the callee CAN accept a BSTR, > then it MUST be passed one, by contract. I would love to hear how the > callee, which is opaque to the caller, can alter its behavior to > accept a simple pointer when it expects a BSTR. > > > ... But in any case the called procedure takes on all > > responsibility. > > Including publishing an interface that the caller must honor. > > > There was no "string memory" going in, and > > hopefully there will be no lingering "string memory" when it > > returns. lol > > I completely disagree, and I have yet to hear the basis for this > claim. Yes, the data can be traced back to a stringtable. But a > stringtable does not contain BSTR, which is what must be passed to an > arbitrary callee. It must be copied to one for passing. > > Gawd, this sounds like a discussion in a C group. (-: understand what is going on. As far a 'basis' goes, you can simply compile a few apps and look. You would discover that VB can be quite variable conditionally on how it handles "strings" (an object, an lpstr, a bstr). I like your use of the term "by contract". In practical use that is probably as good way to view the situation as any. Since when it gets right down to it, it doesn't matter what is really going on - you will get the behavior you expect. -ralph Hi David,
I decided to run a couple of simple tests on this. Having two methods, Foo1(ByVal x as String), and Foo2(ByRef x as string). In both of those methods I just set a form field value to the len(x). So timing calling these methods in large loops, the larger the string being passed in, the larger the difference between ByRef and ByVal. This is because ByVal requires a new BSTR to be created. As these were large loops in the order of millions, it's pretty safe to assume that VB released the created strings immediately. In the first test case I used local variable, later I moved that variable up to a form field level to ensure the compiler could not safely optimize it out. The results were the same and showed the ByVal call taking significantly longer. As the compiler could not know the value of that variable on each iteration, it has to create a new string, but as the memory didn't significantly grow it's safe to say it was releasing them on each iteration. Whether or not this applies outside of loops can only be speculated but one would presume the compiler would do the same thing. Next I ran the tests with a Const string and also with a string literal. There was no difference between the Const variable and literal string in terms of results to each other, but compared to a string variable, they were significantly slower with the ByRef calls. In fact, the ByRef and ByVal calls came in much of a muchness. This makes sense, as the ByRef calls would also require the creation of a new BSTR. so if you had a loop, this : Dim s as String s = "...some large string ........." For i = 0 to count Foo2 s Next i Would be faster than either: Const s = "...some large string ........." For i = 0 to count Foo2 s Next i or For i = 0 to count Foo2 "...some large string ........." Next i This tells us that indeed a new string is being created for the literals and for Const strings as well. Show quoteHide quote "David" <dw85745***@earthlink.net> wrote in message news:uCWWI%23q8JHA.4976@TK2MSFTNGP04.phx.gbl... > If a string is declared locally at the termination of the procedure string > memory should be recovered. > > ===================== > However, when does the compiler recover memory for a string used in an > object declaration: > > Set rsTemp = DaoDb.OpenRecordset("MyTBLName") > > or in a parameter for a called procedure? > > Call MyProcedure("MyTBLName") > > -------------------- > > Logic says: > > 1) For object declaration it would be after execution of the statement -- > Set rsTemp > > 2) For the Called procedure it would also be after the called procedure is > executed. > > OR > > would both strings be considered local to the procedure in which they > reside and not be cleared until that procedures stack is popped? > > ---------------------- > > Also, is there any advantage to clearing a string in a local procedure > that is used early in the procedure and not used again? > > > > > > > > > > > > > > > > > > >
Show quote
Hide quote
"Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message Congratuations, you have provided conclusive and uncontroversial proof thatnews:eoQjVNY9JHA.1336@TK2MSFTNGP05.phx.gbl... > Hi David, > > I decided to run a couple of simple tests on this. Having two methods, > Foo1(ByVal x as String), and Foo2(ByRef x as string). In both of those > methods I just set a form field value to the len(x). So timing calling > these methods in large loops, the larger the string being passed in, the > larger the difference between ByRef and ByVal. This is because ByVal > requires a new BSTR to be created. > As these were large loops in the order of millions, it's pretty safe to > assume that VB released the created strings immediately. In the first test > case I used local variable, later I moved that variable up to a form field > level to ensure the compiler could not safely optimize it out. The results > were the same and showed the ByVal call taking significantly longer. As the > compiler could not know the value of that variable on each iteration, it has > to create a new string, but as the memory didn't significantly grow it's > safe to say it was releasing them on each iteration. Whether or not this > applies outside of loops can only be speculated but one would presume the > compiler would do the same thing. > > Next I ran the tests with a Const string and also with a string literal. > There was no difference between the Const variable and literal string in > terms of results to each other, but compared to a string variable, they were > significantly slower with the ByRef calls. In fact, the ByRef and ByVal > calls came in much of a muchness. This makes sense, as the ByRef calls would > also require the creation of a new BSTR. > so if you had a loop, this : > > Dim s as String > s = "...some large string ........." > For i = 0 to count > Foo2 s > Next i > > Would be faster than either: > > Const s = "...some large string ........." > For i = 0 to count > Foo2 s > Next i > > or > > For i = 0 to count > Foo2 "...some large string ........." > Next i > > > This tells us that indeed a new string is being created for the literals and > for Const strings as well. > if one Declares a String variable in VB, VB provides one! [The crowd cheers! It is pandemonium in the Hall!] Hi Ralph,
Show quoteHide quote "Ralph" <nt_consultin***@yahoo.com> wrote in message And it conclusively proves your statements about pointers to the string news:e3mCLta9JHA.1336@TK2MSFTNGP05.phx.gbl... > > "Bill McCarthy" <TPASoft.com Are Identity Thieves> wrote in message > news:eoQjVNY9JHA.1336@TK2MSFTNGP05.phx.gbl... >> Hi David, >> >> I decided to run a couple of simple tests on this. Having two methods, >> Foo1(ByVal x as String), and Foo2(ByRef x as string). In both of those >> methods I just set a form field value to the len(x). So timing calling >> these methods in large loops, the larger the string being passed in, the >> larger the difference between ByRef and ByVal. This is because ByVal >> requires a new BSTR to be created. >> As these were large loops in the order of millions, it's pretty safe to >> assume that VB released the created strings immediately. In the first >> test >> case I used local variable, later I moved that variable up to a form >> field >> level to ensure the compiler could not safely optimize it out. The > results >> were the same and showed the ByVal call taking significantly longer. As > the >> compiler could not know the value of that variable on each iteration, it > has >> to create a new string, but as the memory didn't significantly grow it's >> safe to say it was releasing them on each iteration. Whether or not this >> applies outside of loops can only be speculated but one would presume the >> compiler would do the same thing. >> >> Next I ran the tests with a Const string and also with a string literal. >> There was no difference between the Const variable and literal string in >> terms of results to each other, but compared to a string variable, they > were >> significantly slower with the ByRef calls. In fact, the ByRef and ByVal >> calls came in much of a muchness. This makes sense, as the ByRef calls > would >> also require the creation of a new BSTR. >> so if you had a loop, this : >> >> Dim s as String >> s = "...some large string ........." >> For i = 0 to count >> Foo2 s >> Next i >> >> Would be faster than either: >> >> Const s = "...some large string ........." >> For i = 0 to count >> Foo2 s >> Next i >> >> or >> >> For i = 0 to count >> Foo2 "...some large string ........." >> Next i >> >> >> This tells us that indeed a new string is being created for the literals > and >> for Const strings as well. >> > > Congratuations, you have provided conclusive and uncontroversial proof > that > if one Declares a String variable in VB, VB provides one! > > [The crowd cheers! It is pandemonium in the Hall!] > table were wrong. I guess that accounts for the sarcasm in your post "Bill McCarthy" <Bill McCarthy Is A Liar and A Thief> wrote in message Why are you still infesting the VB6 group McCarthy? And why do you almost news:OIr6TJg9JHA.4168@TK2MSFTNGP05.phx.gbl... > some typical McCarthy rubbish never post in the VB.Net group? Are your MVP handlers still banning you from posting there? Mike
Web Pages in a VB Window?
Inno Setup and Dependencies Download multiple files concurrently using WinHttpRequest When the compiler freezes.... what is the rescue? How to Change $(AppPath) in PDWizard? can i do this with real database, not just dataset The JET VBA File...Help Please! Proxy + ADO + VB6... Macro to Print Text to file in UTF-8 JPEG File Compression |
|||||||||||||||||||||||