This is an automated email from the ASF dual-hosted git repository. garydgregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-codec.git
commit 72e2540a4b302fa0434e605b75d5a764fc226fba Author: Gary Gregory <[email protected]> AuthorDate: Thu Aug 6 07:40:05 2026 -0400 Optimize honeticEngine.encode(String, LanguageSet) for speed. --- src/changes/changes.xml | 1 + .../commons/codec/language/bm/PhoneticEngine.java | 25 ++++++++++++++++++++-- .../codec/language/bm/BeiderMorseEncoderTest.java | 6 ++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 9b38caeb..ba60f6cd 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -45,6 +45,7 @@ The <action> type attribute can be add,update,fix,remove. <body> <release version="1.22.2" date="YYYY-MM-DD" description="This is a feature and maintenance release. Java 8 or later is required."> <!-- FIX --> + <action type="fix" dev="ggregory" due-to="Yu Bao, Gary Gregory">Optimize honeticEngine.encode(String, LanguageSet) for speed.</action> <!-- ADD --> <!-- UPDATE --> </release> diff --git a/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java b/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java index a08d7067..5a13a7d5 100644 --- a/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java +++ b/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java @@ -387,8 +387,13 @@ public class PhoneticEngine { input = input.toLowerCase(Locale.ENGLISH).replace('-', ' ').trim(); if (this.nameType == NameType.GENERIC) { - if (input.startsWith("d'")) { // check for d' - final String remainder = input.substring(2); + final String dQuotePrefix = "d'"; + final int dqpLen = dQuotePrefix.length(); + if (input.startsWith(dQuotePrefix)) { // check for d' + String remainder = input.substring(dqpLen); + // Find remainder without allocating new string. + final int start = lastRepeat(remainder, dQuotePrefix, dqpLen); + remainder = remainder.substring(start); final String combined = "d" + remainder; return "(" + encode(remainder) + ")-(" + encode(combined) + ")"; } @@ -503,4 +508,20 @@ public class PhoneticEngine { public boolean isConcat() { return this.concat; } + + private int lastRepeat(final String source, final String prefix, final int prefixLen) { + // Find without allocating new string. + int start = 0; + while (start + prefixLen <= source.length()) { + int i = 0; + while (i < prefixLen && source.charAt(start + i) == prefix.charAt(i)) { + i++; + } + if (i != prefixLen) { + break; + } + start += prefixLen; + } + return start; + } } diff --git a/src/test/java/org/apache/commons/codec/language/bm/BeiderMorseEncoderTest.java b/src/test/java/org/apache/commons/codec/language/bm/BeiderMorseEncoderTest.java index 0dd274b4..56cfe3cf 100644 --- a/src/test/java/org/apache/commons/codec/language/bm/BeiderMorseEncoderTest.java +++ b/src/test/java/org/apache/commons/codec/language/bm/BeiderMorseEncoderTest.java @@ -30,6 +30,7 @@ import java.util.regex.Pattern; import org.apache.commons.codec.AbstractStringEncoderTest; import org.apache.commons.codec.EncoderException; import org.apache.commons.codec.StringEncoder; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; /** @@ -93,6 +94,11 @@ class BeiderMorseEncoderTest extends AbstractStringEncoderTest<StringEncoder> { } } + @Test + void testDQuoteRepeat() throws Exception { + assertEquals("(D|a|i|o)-(dD|da|di|do)", new BeiderMorseEncoder().encode(StringUtils.repeat("d'", 20000) + "aaa")); + } + @Test void testEncodeAtzNotEmpty() throws EncoderException { final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
