Re: [v8-users] V8 uses huge amounts of memory for "dictionary" objects with ~50 properties

2017-04-13 Thread Russ P
Thanks for the fast reply.  I did notice a big jump from 40 to 50 entries, 
but I just figured some internal representation had changed due to the size 
increasing.  Your explanation makes a lot more sense.  I agree that a 4x 
growth rate is odd, I've usually seen 2x in C/C++ libs.

Normally I would use the constructor to initialize everything exactly as 
you say, but I can't do it in this case -- there are about 300 or so 
possible property names, but usually around 10 - 70 of them actually get 
filled in per object.  It's a somewhat odd use case, but it was still 
surprising to see such high memory overhead compared to other browsers. 
 I'm glad to hear you're working on improving the dictionary-mode object, 
hopefully that 4x growth bug can be fixed at some point too!

Russ

On Thursday, April 13, 2017 at 5:15:01 AM UTC-7, Jakob Kummerow wrote:
>
> We are aware that dictionary-mode objects are not particularly memory 
> efficient right now, and are working on improving that.
>
> With the current implementation, every used entry in a property dictionary 
> requires 3 words (=8 bytes each on 64-bit), one word each for the 
> property's name, value, and details (writable/enumerable/configurable).
> Additionally, dictionaries grow when usage exceeds 2/3 of capacity; this 
> is in order to keep the probability of collisions low.
> When they grow, they grow by a factor of 4x. (That smells like a bug; I 
> would guess that the intention was to let them grow by 2x, but the 
> multiplication is done twice.)
>
> What ends up happening is that for objects with 43 properties, the 
> dictionary has capacity 64, consuming 64 * 3 (words per entry) * 8 (bytes 
> per word) = 1536 bytes (+ 7 words metadata). When you add the 44th 
> property, it is grown to capacity 256, now consuming 256 * 3 * 8 = 6144 
> bytes (+7 words metadata). On the bright side, you can then grow your 
> objects all the way up to 170 properties without increasing memory usage. 
> So the overhead you're measuring will depend a lot on just how many 
> properties you're adding.
>
>
> Side note: if you know the set of properties that will be added in advance 
> (just not their order), then it might be a good idea to initialize all of 
> them in the object's constructor, and fill in their actual values later, so 
> that you'll benefit from faster and slimmer objects. Roughly:
> function MyObject() {
>   this.prop1 = undefined;
>   this.prop2 = undefined;
>   // etc...
> }
> function OnNetworkReceived(object, prop, value) {
>   object[prop] = value;  // prop is "prop1" or "prop2" or ...
> }
>
>
> On Thu, Apr 13, 2017 at 1:20 PM, Russ P > 
> wrote:
>
>> Hello,
>>
>> I've been working on a project that adds properties to objects in a 
>> variable order as they come in over the network (hidden classes and similar 
>> optimizations can't be applied). I've noticed that V8, on both Chrome and 
>> Node, uses huge amounts of memory to represent them compared to other JS 
>> engines.  I'm testing on Windows.
>>
>> In 64-bit V8, an object with 50 simple properties with integer values 
>> uses ~6000 bytes of memory, which works out to >100 bytes overhead per 
>> entry.  32-bit is somewhat better at ~3000 bytes per object and >45 bytes 
>> overhead per entry, but it's still really bad.
>>
>> In comparison, the same 50-property objects were only ~900 bytes each in 
>> Firefox and Edge.  That's 3-6X less!
>>
>> I've included a test that shows the issue if you'd like to try it out: 
>> https://repl.it/HIMc/7.  Be sure to turn off infinite loop protection in 
>> settings.  After running it, you can force a gc and check the browser's 
>> memory usage (divide by 20, that's the test # of objects).
>>
>> Anyone else seen similar problems?  That seems like a crazy amount of 
>> overhead per property.
>>
>> -Russ
>>
>> -- 
>> -- 
>> v8-users mailing list
>> v8-u...@googlegroups.com 
>> http://groups.google.com/group/v8-users
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "v8-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to v8-users+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [v8-users] V8 uses huge amounts of memory for "dictionary" objects with ~50 properties

2017-04-13 Thread Jakob Kummerow
We are aware that dictionary-mode objects are not particularly memory
efficient right now, and are working on improving that.

With the current implementation, every used entry in a property dictionary
requires 3 words (=8 bytes each on 64-bit), one word each for the
property's name, value, and details (writable/enumerable/configurable).
Additionally, dictionaries grow when usage exceeds 2/3 of capacity; this is
in order to keep the probability of collisions low.
When they grow, they grow by a factor of 4x. (That smells like a bug; I
would guess that the intention was to let them grow by 2x, but the
multiplication is done twice.)

What ends up happening is that for objects with 43 properties, the
dictionary has capacity 64, consuming 64 * 3 (words per entry) * 8 (bytes
per word) = 1536 bytes (+ 7 words metadata). When you add the 44th
property, it is grown to capacity 256, now consuming 256 * 3 * 8 = 6144
bytes (+7 words metadata). On the bright side, you can then grow your
objects all the way up to 170 properties without increasing memory usage.
So the overhead you're measuring will depend a lot on just how many
properties you're adding.


Side note: if you know the set of properties that will be added in advance
(just not their order), then it might be a good idea to initialize all of
them in the object's constructor, and fill in their actual values later, so
that you'll benefit from faster and slimmer objects. Roughly:
function MyObject() {
  this.prop1 = undefined;
  this.prop2 = undefined;
  // etc...
}
function OnNetworkReceived(object, prop, value) {
  object[prop] = value;  // prop is "prop1" or "prop2" or ...
}


On Thu, Apr 13, 2017 at 1:20 PM, Russ P  wrote:

> Hello,
>
> I've been working on a project that adds properties to objects in a
> variable order as they come in over the network (hidden classes and similar
> optimizations can't be applied). I've noticed that V8, on both Chrome and
> Node, uses huge amounts of memory to represent them compared to other JS
> engines.  I'm testing on Windows.
>
> In 64-bit V8, an object with 50 simple properties with integer values uses
> ~6000 bytes of memory, which works out to >100 bytes overhead per entry.
>  32-bit is somewhat better at ~3000 bytes per object and >45 bytes overhead
> per entry, but it's still really bad.
>
> In comparison, the same 50-property objects were only ~900 bytes each in
> Firefox and Edge.  That's 3-6X less!
>
> I've included a test that shows the issue if you'd like to try it out:
> https://repl.it/HIMc/7.  Be sure to turn off infinite loop protection in
> settings.  After running it, you can force a gc and check the browser's
> memory usage (divide by 20, that's the test # of objects).
>
> Anyone else seen similar problems?  That seems like a crazy amount of
> overhead per property.
>
> -Russ
>
> --
> --
> v8-users mailing list
> v8-users@googlegroups.com
> http://groups.google.com/group/v8-users
> ---
> You received this message because you are subscribed to the Google Groups
> "v8-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to v8-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[v8-users] V8 uses huge amounts of memory for "dictionary" objects with ~50 properties

2017-04-13 Thread Russ P
Hello,

I've been working on a project that adds properties to objects in a 
variable order as they come in over the network (hidden classes and similar 
optimizations can't be applied). I've noticed that V8, on both Chrome and 
Node, uses huge amounts of memory to represent them compared to other JS 
engines.  I'm testing on Windows.

In 64-bit V8, an object with 50 simple properties with integer values uses 
~6000 bytes of memory, which works out to >100 bytes overhead per entry. 
 32-bit is somewhat better at ~3000 bytes per object and >45 bytes overhead 
per entry, but it's still really bad.

In comparison, the same 50-property objects were only ~900 bytes each in 
Firefox and Edge.  That's 3-6X less!

I've included a test that shows the issue if you'd like to try it 
out: https://repl.it/HIMc/7.  Be sure to turn off infinite loop protection 
in settings.  After running it, you can force a gc and check the browser's 
memory usage (divide by 20, that's the test # of objects).

Anyone else seen similar problems?  That seems like a crazy amount of 
overhead per property.

-Russ

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.