Is it inefficient to use implicit struct creation

2019-08-15 02:13发布

问题:

Bear with me on this...

Say I have an existing struct:

<cfset struct1 = {key1 = "foo", key2 = "bar"}>

...to which I want to add some key/value pairs. The typical approach would be something like:

<cfset struct1.key3 = "baz">
<cfset struct1.key4 = "qux">
<cfset struct1.key5 = "quux">

Alternatively, I could use structAppend():

<cfset struct2 = {key3 = "baz", key4 = "qux", key5 = "quux"}>
<cfset structAppend(struct1, struct2, false)>

... which has the added bonus of allowing me to control whether preexisting keys are overwritten. The disadvantage, I assume, is that it uses more memory since the new key/value pairs will end up existing in two different places. But what if I do this instead:

<cfset structAppend(struct1, {key3 = "baz", key4 = "qux", key5 = "quux"})>

Have I eliminated the extra memory usage? Or, will the second parameter's struct continue to exist in some secret location after the function has executed-- in which case I'm now wasting memory on a redundant set of keys/values that I can't even access.

Although my primary concern is memory usage, it probably wouldn't hurt to know if the last approach has any other disadvantages, such as processing overhead, compared to the first. And I realize that the differences in resource usage between any of the methods I presented will not be significant in a single execution scenario. I'm thinking on a larger scale, with lots of data and/or many repetitions.

I'm currently on CF 9.0.1, if that matters.

回答1:

Yeah, the implicit struct will hang around in memory until the next GC decides it needs to be cleaned up. But it'll get created just the same with either of your structAppend() examples. The only difference is that the struct2 reference never gets created if you do it inline.

I suppose if a GC happened in the middle of a request, the inline version would more quickly become a candidate to be cleaned up as there will - implicitly - be zero references still using it, whereas if you give it a name, there's a reference right there, and it won't be available for GC until after the end of the request when the reference itself gets destroyed.