From df2c1f9684c603779436dbe577ae131d3821d62e Mon Sep 17 00:00:00 2001 From: Arbousier1 Date: Sat, 18 Jul 2026 10:28:13 +0800 Subject: [PATCH] perf(core): specialize string fingerprint fields and inline separators Add a field(String) overload so the hot fingerprint path appends string fields directly via StringBuilder.append(String) instead of routing through Objects.toString in the field(Object) overload. Replace the Objects.toString(value, "") call with an explicit null check to avoid the wrapper allocation, and inline appendFieldSeparator/finishField so each field(...) overload emits the separator and flag update in the same frame. Behavior is unchanged: null fields still append nothing, non-null fields still append toString(), and raw/entrySeparator keep their existing semantics. --- .../core/DelimitedFingerprintBuilder.java | 56 +++++++++++-------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/src/main/java/top/ellan/mahjong/table/core/DelimitedFingerprintBuilder.java b/src/main/java/top/ellan/mahjong/table/core/DelimitedFingerprintBuilder.java index a675967..d7b1522 100644 --- a/src/main/java/top/ellan/mahjong/table/core/DelimitedFingerprintBuilder.java +++ b/src/main/java/top/ellan/mahjong/table/core/DelimitedFingerprintBuilder.java @@ -1,7 +1,5 @@ package top.ellan.mahjong.table.core; -import java.util.Objects; - public final class DelimitedFingerprintBuilder { private final StringBuilder delegate; private boolean needsSeparator; @@ -14,28 +12,53 @@ public static DelimitedFingerprintBuilder create(int capacity) { return new DelimitedFingerprintBuilder(capacity); } + public DelimitedFingerprintBuilder field(String value) { + if (this.needsSeparator) { + this.delegate.append(':'); + } + if (value != null) { + this.delegate.append(value); + } + this.needsSeparator = true; + return this; + } + public DelimitedFingerprintBuilder field(Object value) { - this.appendFieldSeparator(); - this.delegate.append(Objects.toString(value, "")); - return this.finishField(); + if (this.needsSeparator) { + this.delegate.append(':'); + } + if (value != null) { + this.delegate.append(value); + } + this.needsSeparator = true; + return this; } public DelimitedFingerprintBuilder field(boolean value) { - this.appendFieldSeparator(); + if (this.needsSeparator) { + this.delegate.append(':'); + } this.delegate.append(value); - return this.finishField(); + this.needsSeparator = true; + return this; } public DelimitedFingerprintBuilder field(char value) { - this.appendFieldSeparator(); + if (this.needsSeparator) { + this.delegate.append(':'); + } this.delegate.append(value); - return this.finishField(); + this.needsSeparator = true; + return this; } public DelimitedFingerprintBuilder field(int value) { - this.appendFieldSeparator(); + if (this.needsSeparator) { + this.delegate.append(':'); + } this.delegate.append(value); - return this.finishField(); + this.needsSeparator = true; + return this; } public DelimitedFingerprintBuilder raw(Object value) { @@ -49,17 +72,6 @@ public DelimitedFingerprintBuilder entrySeparator() { return this; } - private void appendFieldSeparator() { - if (this.needsSeparator) { - this.delegate.append(':'); - } - } - - private DelimitedFingerprintBuilder finishField() { - this.needsSeparator = true; - return this; - } - @Override public String toString() { return this.delegate.toString();