Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store binary-encoded simple tags inside CompoundTag and ListTag instead of useless boxing objects #126

Open
dktapps opened this issue Jan 9, 2025 · 1 comment

Comments

@dktapps
Copy link
Member

dktapps commented Jan 9, 2025

User code rarely interacts with the likes of IntTag directly. It's also horribly inefficient to box integers this way.
In addition, extra objects means extra work for the GC.

All simple tags (byte, short, int, long, string, byte[], float, double, int[]) could be easily stored as string inside CompoundTag and ListTag, avoiding the need for a ton of unnecessary object allocations. This string would essentially just be chr($tagType) . LittleEndianNbtSerializer::writeHeadless($tagValue).

Brief investigation shows that integer-like tags ByteTag, ShortTag, etc take up a minimum of 80 bytes of memory. Encoded as strings, these would take 32 bytes each instead (the aligned size of zend_string). StringTag, ByteArrayTag and IntTag would be larger (depending on the size of their contained values).
(We could even use int for types smaller than 8 bytes on 64-bit platforms, which would avoid extra allocations completely.)

The only potential caveat to this is that packing the values into a binary form would be kinda slow because the NBT serializers currently have crap performance. However, it's possible that the cost of allocating Tag objects might outweigh this anyway.

There's also the consideration that if CompoundTag->getTag() or getValue() were used, we'd have to convert the strings into tag objects anyway. So this would mostly benefit from use of stuff like CompoundTag->getInt() where we could just directly convert the internal string binary into an int value without allocating any objects.

@dktapps dktapps changed the title Store binary-encoded simple tags inside CompoundTag and ListTag instead of useless boxed objects Store binary-encoded simple tags inside CompoundTag and ListTag instead of useless boxing objects Jan 9, 2025
@dktapps
Copy link
Member Author

dktapps commented Jan 31, 2025

Another option could be to embed a type info byte into the CompoundTag keys. However, this might be more complex to implement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant