Community listing page, reviews here may not be monitored by the author.
Lean Object
No reviews yet
Deduplicates Minecraft's hottest lookup objects so comparisons become pointer compares instead of string compares
Community voices
Reviews
No reviews yet. Be the first to review this project!
Get it on
Available Platforms
About
Project Details
For authors
Embed Badge
If you're the author of this project, you can embed a live badge anywhere that supports HTML or Markdown. It updates automatically whenever ratings change.
Use HTML for any page that supports it, or Markdown for README files and Markdown-based descriptions.
Identifiers
Platform IDs
About
Description
Lean Object makes Minecraft's most-used lookup objects cheaper, by deduplicating them. When a value exists exactly once, comparing it becomes a pointer compare instead of a string compare — and that comparison happens on every registry lookup, tag check and ingredient match.
Download the file that matches your Minecraft version and mod loader.
Why deduplication makes things faster
A hash code only picks the bucket. Every collision inside that bucket is then resolved with equals(), and that is where the expensive work happens — for a tag key, comparing a registry key and a location, i.e. string chains. Modded packs make this worse: thousands of identifiers sharing prefixes like minecraft: or mymod: have hash codes that cluster, so the buckets where comparisons pile up are exactly the busy ones.
Keep only one instance per logical value, and equals can be reduced to o == this and hashCode to System.identityHashCode. Every one of those comparisons becomes a pointer compare. Less memory is a side effect of the same change, not the goal.
Features
All features are on by default and can be switched off individually in config/leanobject.toml.
| Feature | What it does |
|---|---|
| ResourceLocation | One shared instance per id. The duplicate instances and their strings disappear, and location comparisons stop being string comparisons, which is what registry and model lookups spend their time on. |
| TagKey | Custom interning replaces the vanilla interner, and equals/hashCode become identity based. Tag membership tests are the hottest path in most packs. |
| ResourceKey | Registry keys are built with a single cache probe instead of filling the vanilla intern map, so key creation is cheaper and allocates less. |
| Ingredient | Single-entry ingredients reuse one shared instance, so recipes stop rebuilding identical Ingredient objects and their lazily built item arrays. |
| NBT containers | Replaces the maps and lists inside the tag classes with leaner equivalents, at the allocation site, so the vanilla containers are never created. |
| Model objects | Leaner containers for baked block and item models. Client side. |
| AE2 storage keys | Deduplicates AE2's item and fluid storage keys, so a large ME network stops allocating and hashing a key per lookup. Requires AE2. |
Features that target another mod are only applied when that mod is present, and skipped otherwise — AE2, Farmer's Delight and FerriteCore are all handled this way, and none of them has to be configured by hand. Since the mods available for a given Minecraft version differ, the exact set of features can differ between files; config/leanobject.toml always lists the ones that file supports.
Playing a tech pack? Turn on AE2 key deduplication
AE2 itself has no interning for storage keys: every factory builds a fresh key object and hashes its contents, so a late-game ME network is little but keys — banks of interfaces, storage buses, import/export buses and crafting CPUs hold enormous numbers of them, all allocated on demand and compared by value.
That is exactly the workload this feature targets, and it speeds up key creation, not just key lookup:
- A key without components becomes a shared instance lookup — no allocation and no hashing at all.
- A key carrying components costs one cache probe keyed by those components, and that is the entire cost. Only the first probe for a given value allocates anything; repeats return the existing key.
- With keys existing once, comparisons become reference checks, and the hash the key caches is the identity hash — which is what a large network spends its time on.
- The packet reader and the serialization codecs are routed through the same cache, so keys that arrive over the network or are loaded from disk are shared too.
In a modded pack this happens constantly. AE2 rarely works on its own storage: storage buses, import and export buses and interfaces connect the ME network to other mods' inventories — chests, barrels, machines, drawers, pipes — and every item moved across that boundary is converted between an ItemStack and an AE key. Those transfers run continuously in bulk, per item, per bus, per tick. A shared instance per logical key turns that conversion into a cache probe instead of an allocation plus a hash.
Supersedes Fast Tag
Lean Object replaces Fast Tag and is meant to be used instead of it. The TagKey and ResourceKey features come from it — the same methods are replaced, with the same reasoning, and interning keys are compared by reference in both. What changed is the cache backend: Fast Tag used Guava's MapMaker and reflection into its internals, Lean Object uses its own caches with plain identity maps and no reflection.
Do not install both. They replace the same methods, and the last one applied wins.
Configuration
config/leanobject.toml is regenerated on every launch:
enabled = true # master switch
loggingInGC = true # force a GC and log heap usage when joining a world
[features.tagKey]
safeMode = false # false = replace the methods, true = wrap the original ones
enabled = true
safeMode applies to the features that ship a non-destructive variant. Set it to true if another mod conflicts with the replacing path: it wraps the original methods instead, which is more compatible but slightly slower, and it gives up the identity comparison.
Compatibility notes
- FerriteCore is handled automatically. Where FerriteCore caches the same model location call this mod replaces, its own handling is switched off — two replacements cannot both inject into one instruction. This needs a FerriteCore build that allows other mods to disable an option.
- Injection conflicts. Most features replace methods outright. If another mod modifies the same target, the two fight and the last one applied wins. The model feature in particular is known to conflict on large packs; it can be turned off on its own.
- Reference equality. Interned keys compare by reference, so a value created outside the interning entry points will not compare equal to its interned twin. Where a feature ships a non-destructive variant, switching to it keeps value comparison instead.
- AE2 support is version specific. It hooks private members of AE2's key classes, so forks or other builds of AE2 can change those internals — in which case the feature fails to apply loudly rather than misbehaving.
- Optional integrations are auto-detected. Features whose mod is not installed are skipped automatically.
- Location interning costs CPU as well as saving memory. Locations are constructed extremely often, and interning adds a cache probe to every construction. It pays off when the same id is created repeatedly; it can cost CPU on hot paths that keep producing distinct ids, where nothing gets shared. If you are chasing CPU rather than memory, try turning this one feature off first.
Building from source
./gradlew build
Licensed under the GNU LGPL v3.0 or later.
Screenshots
Gallery
Versions
Files
Relations
Project Relations
More like this
Similar Mods
Suggestions use data such as tags, dependencies, dependents, descriptions, titles, and more to rank how much they overlap with this mod.
On ModDex
Community snapshot
By the numbers
Statistics
Want to reach Minecraft players?
We're looking for a server hosting partner to feature here and other parts of the site. Interested? Send us a message!
Get in touchGet it on
Available Platforms
On ModDex
Community snapshot
By the numbers