by reference variable = memory efficiency question
I'm building SQL statements with a bunch of values from a dataset. Obviously that gives some really long names to put inline or even in parameter.addwithvalue code so beforehand I just declare a bunch of variables with really short names and assign them to the DS's exact fields like:
strFName = dsXML.Tables("owner").Rows(x).Item("owner_first")
so then my add parameter code looks really short and pretty :P
m_nonQCMD.Parameters.AddWithValue("@strFName", strFName)
but this way I'm putting all the data in the dataset into memory twice by copying it into a new variable, right? So I was thinking, if it's just a string variable representing a field on the dataset, why not declare it by reference so the variable is basically a handy nickname pointing to that field in the dataset.
Will it even work to have a string declared by reference and connected to one value inside of a dataset? And if so, will that stop duplicating everything in memory? And if so...:blush: I forgot how to declare a variable as a reference to another variable instead of the normal way in VB. Strangely I remember how to do it in C++ but not VB lol. Someone should totally tell me :bigyello:
Re: by reference variable = memory efficiency question
It's already a 'reference'. You don't 'copy' anything twice (unless it's a value type, which I suspect it isn't; it's a string?) you simply have a reference to that object.
Re: by reference variable = memory efficiency question
Actually, I believe that Item() will return an Object. You would need to return Item().ToString to get a string from that, unless you have Option Strict OFF, in which case you are doing an implicit conversion of the Object to String.
Either way, every variable takes up some memory. A reference is going to take up some space, just like anything else. Since you are talking about a data item that looks like it is probably a first name, then it is likely that the variable, whatever it is, is not going to be all that much shorter than a copy of the string. Perhaps it would be 20% of the size of the string. Big deal. If you are worried about that amount, then you should just be writing out the whole thing, since you have already noted that the advantage to your current practice is only that it makes the code neater. Sure, it wastes a small amount of memory, but a matter of bytes per instance, which is not that big an issue these days. If it makes the code easier for you to read, then it is easier to maintain, and that, alone, probably justifies the waste of memory.
Re: by reference variable = memory efficiency question
well it does run on a modern PC and not some mainframe or cell phone so it's not the end of the world either way :p but I thought reference variables were basically a glorified enumeration. I know the syntax is wrong on this one but pretend it isn't :P
Dim strHello1 as string = "hello this is Desolator"
Dim ByRef strHello2 = strHello1
I thought the compiler in that case would strip off the names and treat every reference to strHello2 as a reference to strHello1 and they both point to the same location in memory so the second one doesn't take up any additional memory at all. The two names for the same spot in memory is just for human purposes. Maybe VB doesn't work that way though, as I learned that in C++ class.
Anyway, I think Shaggy is right. Item would probably return some sort of OleDB object and if I add .tostring, it wouldn't reference the object, just the result of the tostring sub which I believe is created on the fly in addition to the original object. I don't think there's an item(0).value either or anything else that would let me reference just that one spot in memory directly. Ohhhhh welllllll, it'll just have to be inefficient. That or I'll change it over to use the full thing.
Although, is there a way to actually use some sort of enumeration just in the code so I can call dsXML.Tables("owner").Rows(x).Item("owner_first") something else just in the code for my purposes without actually declaring a new variable? Isn't there some crazy trick with the With or Using keywords, which btw I never use and forgot what they exactly do :P
Re: by reference variable = memory efficiency question
Dim s1 as string = "Fred"
Dim s2 as string = s1
Both s1 and s2 point to the same string. There's no duplication. String s1 can be a million characters in length; they would both point to the same string (and, indeed, would 'equal' each other).
Strings are a bit funky, though, in that once they are created they can never be changed. The phrase that is bandied about is 'immutable'.
There isn't any inefficiency at all, beyond the fact that an intermediate variable would be created to hold a reference to the object in question. The few bytes or so is really not an issue if you are using objects and code which consumes megabytes of memory.
Re: by reference variable = memory efficiency question
They both point to the same place in memory, but that doesn't mean that the second one takes up no memory. The bit about "point to" means that the variable holds the memory address of the first byte of the memory that holds the object. That address will be four bytes long in a 32 bit system, so the variable will take up four bytes just to hold the pointer. You can NEVER have a variable that takes up no memory.
Re: by reference variable = memory efficiency question
Quote:
Originally Posted by
Shaggy Hiker
Actually, I believe that Item() will return an Object. You would need to return Item().ToString to get a string from that, unless you have Option Strict OFF, in which case you are doing an implicit conversion of the Object to String.
DataRow.Item returns an Object reference but, in this case, the object it refers to is still a String. AddWithValue accepts an Object so casting anything you pass to it is pointless. The method parameter is type Object so whatever you pass in will be referred to as type Object internally anyway. Inside the method its actual type is determined and that becomes the data type for the ADO.NET parameter.
The simple answer to the original question is that you can't declare a variable as a reference. It's either a reference already or it's a value, depending on its type. What you're already doing is all you should, or can, do. That said, there's no need for you to refer back to the DataSet when getting a field value from a row. You should use something like this:
vb.net Code:
Dim table As DataTable = dsXML.Tables("owner")
For Each row As DataRow In table.Rows
m_nonQCMD.Parameters.AddWithValue("@strFName", row("owner_first"))
Your way would require you to use the full path to the field in order to assign to your variable with the short name anyway, so it doesn't really help at all.
Re: by reference variable = memory efficiency question
oh yeah, I keep forgetting the "for each" loop style and that just about everything remotely complicated in the framework is a collection :p I'll change it to look like that.
Btw Whiteley, I got a question about how it actually handles memory in the situation in your example. For example, if I do:
Dim s1 as string = "Fred"
Dim s2 as string = s1
and then the next line is s2 &= " Jones" then s2 would = "Fred Jones" and s1 would still equal "Fred." So by that time they've each got their own separate spots in memory because they're different. I can change one without it affecting the other so they have to have their own memory for each. But before I change the value, do they point to the same place and s2 only gets its own duplicated copy of the data from s1 when the value is changed? That'd be awfully smart if they designed it that way :D
who cares about strings though. A more significant example would be if I was doing graphics work and I did
dim bit1 as whatever.whatever.bitmap = and then assign it some huge bitmap that'd take 100MB of memory.
Then I do:
dim bit2 as whatever.whatever.bitmap = bit1
does it immediately size up bit1, grab that much space in memory, and copy bit1's current data to it and take up another 100MB or does it wait until I alter bit2 in any way before it copies it? Eventually they have to each have their own spots in memory because they're still 100MB each and one line of code can make one different than the other. Let's say my code uses pixel by pixel alterations in a loop to invert the smile on a smiley face bitmap that's contained in bit1. Now I have one smiley bitmap and one frowning bitmap so that's 100MB each and they have to split and have their own spots in memory somewhere along the way. I just wanna know when it happens for future reference in case I ever do anything that requires a lot of memory.
Re: by reference variable = memory efficiency question
Everything that's a class, including String, is a reference type. Everything that's a structure is a value type.
Variables of value types contain the object itself. If you assign the value of one variable to another then you are copying the object. It's exactly for that reason that value types should always be small and relatively simple. The general rule is that anything that occupies over 16 bytes should not be a value type.
Variables of reference types contain a reference to an object, i.e. the memory address of an object. References are really just tarted-up pointers, but they enable us to treat reference type variables and value type variables in essentially the same way, without worrying about the subtleties of pointers that often cause issues. When you assign the value of one reference type variable to another you are copying ONLY a memory address. The size of a memory address depends on the system, so it will be either 4 or 8 bytes, regardless of the size of the object it refers to. A Bitmap variable that refers to a 100 MB Bitmap object will itself occupy only four bytes on a 32-bit system. If you assign the value of myBitmap1 to myBitmap2 then only four bytes are copied and both variables refer to the same 100 MB Bitmap object.
Strings behave in EXACTLY the same way as described above for the Bitmap. The difference is that String objects are immutable. That means that if you try to change a String object what actually happens is that a new String object is created. The original String object still exists and any variables the previously referred to it still do, but the current variable refers to a new String object. E.g.
vb.net Code:
Dim str1 As String = "Hello World"
'A String object containing "Hello World" was created in
'memory and the str1 variable contains its memory address.
Dim str2 As String = str1
'str2 now contains the same memory address as
'str1 so they both refer to the same String object.
str2 &= ", it's me!"
'A new String object was created in memory containing
'"Hello World, it's me!" and str2 now contains its memory address.
'str1 still refers to the original String object.
Re: by reference variable = memory efficiency question
aha, well that's totally not the way I imagined but it makes sense and I can see why they designed it that way. Good thing I learned C++ and know how memory and variables and pointers are really used cuz it totally makes sense. I bet most VB only people imagine variables as just one simple item and it's magically in memory and that's that :P I for one hate all forms of encapsulation of anything anywhere ever :p I always appreciate learning about the behind the scenes workings so I know what my programs are really doing :D thanks!
P.S. but seriously, I hate C++ so much lol.
Re: by reference variable = memory efficiency question
You simply can't have all the power and all the ease of use. There are always trade-offs. C++ has most of the power but is a real pain. VB is easy but does hide a lot. In many cases you don't really need the power and control but it is nice to know what is going on below the surface. Pointers are a fine example. I cut my teeth on C/C++ so I know my way around pointers. As such I understand what references do under the covres. VB doesn't support pointers and I've never missed them. C# does support pointers but I've never had to use that support. I'm not saying that there aren't times when pointers are useful but, for your average line of business app, they just aren't required.
Re: by reference variable = memory efficiency question
Quote:
Originally Posted by
jmcilhinney
DataRow.Item returns an Object reference but, in this case, the object it refers to is still a String. AddWithValue accepts an Object so casting anything you pass to it is pointless. The method parameter is type Object so whatever you pass in will be referred to as type Object internally anyway. Inside the method its actual type is determined and that becomes the data type for the ADO.NET parameter.
That's fine, but the OP was using a two step process: Put the item into a variable of type string, then use the variable in the AddWithParameters. The first step will not work with Option Strict ON because of the implicit cast to type String. The fact that an object is used in the second step is only relevant if the variable in the first step was type Object, which it wasn't.
Re: by reference variable = memory efficiency question
Quote:
Originally Posted by
Shaggy Hiker
That's fine, but the OP was using a two step process: Put the item into a variable of type string, then use the variable in the AddWithParameters. The first step will not work with Option Strict ON because of the implicit cast to type String. The fact that an object is used in the second step is only relevant if the variable in the first step was type Object, which it wasn't.
Indeed. Thinking of what should have been rather than what was.