profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/carterkozak/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
Carter Kozak carterkozak Palantir Raleigh, NC I write code and do other things too!

carterkozak/assertj 0

AssertJ documentation

carterkozak/assertj-core 0

AssertJ is a library providing easy to use rich typed assertions

carterkozak/brave 0

Java distributed tracing implementation compatible with Zipkin backend services.

carterkozak/caffeine 0

A high performance caching library for Java

carterkozak/Cinch 0

A Java library that manages component action/event bindings for MVC patterns

carterkozak/conjure-java 0

Conjure generator for Java clients and servers

carterkozak/conjure-java-runtime-api 0

The API components of the http-remoting RPC library

carterkozak/conscrypt 0

Conscrypt is a Java Security Provider that implements parts of the Java Cryptography Extension and Java Secure Socket Extension.

PR opened palantir/witchcraft-api

Reviewers
Run plugin verification against intellij community and goland no changelog merge when ready

Should provide more confidence in our builds. Everything seems to work.

+9 -1

0 comment

1 changed file

pr created time in 44 minutes

create barnchpalantir/witchcraft-api

branch : ckozak/plugin_verifier

created branch time in an hour

PR opened palantir/witchcraft-api

Add readme widgets and screenshot no changelog merge when ready do not merge

added do-not-merge until the plugin has been approved, the version shield doesn't seem to work until the plugin has been approved by jetbrains.

+13 -0

0 comment

2 changed files

pr created time in 4 hours

push eventpalantir/witchcraft-api

Carter Kozak

commit sha 48f54376ebfd3c4bf55cebcc862366ffe74adc82

Readme widgets

view details

Carter Kozak

commit sha 76267b4bf834c34ef8c975adc4321deefdaaaa53

screenshot

view details

push time in 4 hours

push eventpalantir/witchcraft-api

Carter Kozak

commit sha 3fd26af59af18a4c86c2c9c776acdcb2e816580f

sillier

view details

push time in 4 hours

push eventpalantir/witchcraft-api

Carter Kozak

commit sha 02919605abaab1af249b8ee5170a89cfdf3fea08

let's get silly

view details

push time in 4 hours

push eventpalantir/witchcraft-api

Carter Kozak

commit sha c038a0c862475733251c707afae16b864e71ddfa

one more

view details

push time in 4 hours

push eventpalantir/witchcraft-api

Carter Kozak

commit sha d10df4e658c098ebabdce4163a3a16a32332b78d

hmm

view details

push time in 4 hours

push eventpalantir/witchcraft-api

Carter Kozak

commit sha 76619d4083700d928c2c50ae4e88cfeca6b97114

css?

view details

push time in 4 hours

push eventpalantir/witchcraft-api

Carter Kozak

commit sha 4d0b4eaf061469f372014284fa20f3c8bb686b73

moar stickers

view details

push time in 4 hours

create barnchpalantir/witchcraft-api

branch : ckozak/readme_widgets

created branch time in 5 hours

pull request commentapache/logging-log4j2

LOG4J2-3115: Remember previously computed strings in NamePatternConverter for performance ~3x

My benchmarks were with a single thread only. In practice, is this code executed in multiple log4j2 threads?

As usual, the answer is “it depends” :-) in the default configuration we log synchronously so that all formatting occurs on the application thread which calls into a logger, so contention is bounded by the total number of application threads which may interact with a logger. In most cases access to appender manager instances is guarded to prevent clobbering once the formatted buffer has been generated and must be written. However using asynchronous logging there’s generally one background thread responsible for executing layouts and writing log data to wherever it’s stored, in that case there shouldn’t be contention on the name abbreviator.

The abbreviated name could be stored in the logger itself (all abbreviated names by pattern, to be precise), however this would require substantial architectural changes.

this would certainly be challenging given each logger would need to be aware of all the appenders and their layouts reachable in the configuration. With enough map lookups anything can become slow! Given how (relatively) fast abbreviation is, it’s very possible an attempted optimization would make real-world performance worse.

Do you have profiling data that shows abbreviation as a contributor to overall application congestion? I would imagine there would be many other components more likely to be the limiting factor.

sman-81

comment created time in 5 hours

push eventcarterkozak/logging-log4j2

Markus Spann

commit sha ecbdceeaea432a02b0e00a17b28da6d4a47101bf

LOG4J2-2885: Added support for US-style date patterns and micro/nano seconds (#548) Co-authored-by: Markus Spann <sman81@outlook.de>

view details

Volkan Yazici

commit sha 2bc3b5235aaa1d05ce7081a399ff09f67a86c5d3

LOG4J2-2885 Update changelog.

view details

Carter Kozak

commit sha 609ff5f284e5e916c01b24feeb383cfeebc7d0cb

LOG4J2-3083 Fix slf4j calling class lookup using both accessors `LoggerFactory.getLogger(name/class)` as well as `LoggerFactory.getILoggerFactory().getLogger(name)`.

view details

Carter Kozak

commit sha 59fd1f3f62e3c503c480a933ca360112be520a74

Remove unreleased+replaced StackLocator API from LOG4J2-2940

view details

Volkan Yazici

commit sha ae3f19ac66acf711831535f5db36efd449d5f47a

LOG4J2-3085 Skip certain CI jobs for external PRs.

view details

Andi Büchler

commit sha 73db0bb1a99caa6d0b5872ad909b38d6ee40fcb4

Fix BurstFilter javadoc. (#552)

view details

Carter Kozak

commit sha cb18f36d762154fafd6edfb5c0838ad7d877561e

LOG4J2-3133: log4j-slf4j-impl provides new singleton accessors from slf4j-api 1.7.14 See https://github.com/qos-ch/slf4j/commit/ea3cca72cd5a9329a06b788317a17e806ee8acd0 and https://jira.qos.ch/browse/SLF4J-347

view details

Volkan Yazici

commit sha dbe386b27a0067947f1d87d5b2017fa7861c8398

LOG4J2-2885 Fix the compilation failure caused by the recently added FixedDateFormat entries.

view details

Carter Kozak

commit sha be5b08426f1547b8dd2f7f88968a4e60f0d4c013

Improve worst-case NameAbbreviator performance Previously the entire input string was written to the output buffer, then small sections were deleted or replaced within that string. This meant that for each section that was abbreviated, nearly all following characters from subsequent sections would be migrated, resulting in O(n^2) performance. Now we read from the existing input String, and write sections to the output buffer piece-by-piece. For small strings this may result in more pointer-hopping (may cost ~tens of nanoseconds) while larger values with many abbreviated sections are substantially less expensive. I would expect large "enterprise-grade" class names to perform better than previously. Note that the new approach may result in multiple StringBuilder resize operations in the worst case, where previously writing the original string to the output would have caused it to grow all at once. In most cases we attempt to initialize builders with a reasonable size, so I opted not to add an `ensureCapacity` given the estimated size may be substantially larger than we need. Benchmarks with this change: ``` NamePatternConverterBenchmark.benchNamePatternConverter org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton avgt 3 202.992 ± 1.584 ns/op NamePatternConverterBenchmark.benchNamePatternConverter org.bogus.hokus.pokus.Clazz1 avgt 3 76.517 ± 2.979 ns/op NamePatternConverterBenchmark.benchNamePatternConverter com.bogus.hokus.pokus.Clazz2 avgt 3 75.369 ± 3.217 ns/op NamePatternConverterBenchmark.benchNamePatternConverter edu.bogus.hokus.pokus.a.Clazz3 avgt 3 97.546 ± 12.164 ns/op NamePatternConverterBenchmark.benchNamePatternConverter de.bogus.hokus.b.Clazz4 avgt 3 82.240 ± 14.489 ns/op NamePatternConverterBenchmark.benchNamePatternConverter jp.bogus.c.Clazz5 avgt 3 65.274 ± 3.938 ns/op NamePatternConverterBenchmark.benchNamePatternConverter cn.d.Clazz6 avgt 3 50.239 ± 0.456 ns/op ``` Previous results: ``` NamePatternConverterBenchmark.benchNamePatternConverter org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton avgt 3 209.477 ± 62.262 ns/op NamePatternConverterBenchmark.benchNamePatternConverter org.bogus.hokus.pokus.Clazz1 avgt 3 76.083 ± 8.123 ns/op NamePatternConverterBenchmark.benchNamePatternConverter com.bogus.hokus.pokus.Clazz2 avgt 3 76.109 ± 19.293 ns/op NamePatternConverterBenchmark.benchNamePatternConverter edu.bogus.hokus.pokus.a.Clazz3 avgt 3 91.913 ± 46.029 ns/op NamePatternConverterBenchmark.benchNamePatternConverter de.bogus.hokus.b.Clazz4 avgt 3 74.703 ± 28.086 ns/op NamePatternConverterBenchmark.benchNamePatternConverter jp.bogus.c.Clazz5 avgt 3 59.788 ± 7.298 ns/op NamePatternConverterBenchmark.benchNamePatternConverter cn.d.Clazz6 avgt 3 41.092 ± 19.660 ns/op ```

view details

Carter Kozak

commit sha d22368886c5d7df7171e224398a9f9395175e422

Prefer `indexOf(char)` Note that indexOf(char) performs worse than indexOf(String) on pre-16 JREs due to missing intrinsics for the character implementation. The difference is a few nanoseconds in most cases, so we opt to give the jre as much information as possible for best performance on new runtimes, with the possibility that such optimizations may be back-ported. See https://bugs.openjdk.java.net/browse/JDK-817358

view details

Carter Kozak

commit sha c67a2d856e2775461f249c20057f03c56c1460e4

NamePatternConverterBenchmark uses 4 measurement iterations by default

view details

push time in 5 hours

pull request commentapache/logging-log4j2

Improve worst-case NameAbbreviator performance

Azul Zulu JDK 16.0.2, OpenJDK 64-Bit Server VM, 16.0.2+7

This PR (as is, using indexOf(String, int))

1 (run numbers labeled to account for thermal/scaling issues on my system)

Benchmark                                                                                                                                       (className)  Mode  Cnt    Score   Error  Units
NamePatternConverterBenchmark.benchNamePatternConverter  org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton  avgt    4  195.817 ± 7.506  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        org.bogus.hokus.pokus.Clazz1  avgt    4   74.693 ± 0.583  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        com.bogus.hokus.pokus.Clazz2  avgt    4   74.509 ± 2.908  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                      edu.bogus.hokus.pokus.a.Clazz3  avgt    4   90.755 ± 0.650  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                             de.bogus.hokus.b.Clazz4  avgt    4   78.861 ± 0.699  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                   jp.bogus.c.Clazz5  avgt    4   66.118 ± 2.626  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                         cn.d.Clazz6  avgt    4   49.765 ± 5.760  ns/op

4

Benchmark                                                                                                                                       (className)  Mode  Cnt    Score    Error  Units
NamePatternConverterBenchmark.benchNamePatternConverter  org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton  avgt    4  195.953 ± 13.193  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        org.bogus.hokus.pokus.Clazz1  avgt    4   74.750 ±  2.435  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        com.bogus.hokus.pokus.Clazz2  avgt    4   80.890 ± 29.628  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                      edu.bogus.hokus.pokus.a.Clazz3  avgt    4   92.087 ±  3.809  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                             de.bogus.hokus.b.Clazz4  avgt    4   79.318 ±  3.140  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                   jp.bogus.c.Clazz5  avgt    4   62.846 ±  1.945  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                         cn.d.Clazz6  avgt    4   48.112 ±  4.871  ns/op

This PR, but using indexOf(char, int)

2

Benchmark                                                                                                                                       (className)  Mode  Cnt    Score    Error  Units
NamePatternConverterBenchmark.benchNamePatternConverter  org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton  avgt    4  179.839 ±  8.086  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        org.bogus.hokus.pokus.Clazz1  avgt    4   75.254 ± 11.107  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        com.bogus.hokus.pokus.Clazz2  avgt    4   74.735 ±  3.403  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                      edu.bogus.hokus.pokus.a.Clazz3  avgt    4   85.463 ±  1.292  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                             de.bogus.hokus.b.Clazz4  avgt    4   71.888 ±  3.801  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                   jp.bogus.c.Clazz5  avgt    4   59.703 ± 14.708  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                         cn.d.Clazz6  avgt    4   44.177 ±  1.026  ns/op

5

Benchmark                                                                                                                                       (className)  Mode  Cnt    Score    Error  Units
NamePatternConverterBenchmark.benchNamePatternConverter  org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton  avgt    4  178.932 ± 23.631  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        org.bogus.hokus.pokus.Clazz1  avgt    4   70.855 ±  1.261  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        com.bogus.hokus.pokus.Clazz2  avgt    4   71.347 ±  3.361  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                      edu.bogus.hokus.pokus.a.Clazz3  avgt    4   82.970 ±  0.842  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                             de.bogus.hokus.b.Clazz4  avgt    4   71.882 ±  3.248  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                   jp.bogus.c.Clazz5  avgt    4   58.917 ±  2.620  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                         cn.d.Clazz6  avgt    4   42.353 ±  0.672  ns/op

Original implementation from release-2.x

3

Benchmark                                                                                                                                       (className)  Mode  Cnt    Score   Error  Units
NamePatternConverterBenchmark.benchNamePatternConverter  org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton  avgt    4  201.906 ± 2.327  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        org.bogus.hokus.pokus.Clazz1  avgt    4   73.014 ± 3.037  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        com.bogus.hokus.pokus.Clazz2  avgt    4   74.045 ± 2.914  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                      edu.bogus.hokus.pokus.a.Clazz3  avgt    4   89.466 ± 1.284  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                             de.bogus.hokus.b.Clazz4  avgt    4   69.703 ± 2.335  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                   jp.bogus.c.Clazz5  avgt    4   53.735 ± 0.696  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                         cn.d.Clazz6  avgt    4   39.654 ± 0.318  ns/op

6

Benchmark                                                                                                                                       (className)  Mode  Cnt    Score    Error  Units
NamePatternConverterBenchmark.benchNamePatternConverter  org.bogus.hokus.pokus.org.bogus.hokus.pokus.org.bogus.hokus.pokus.RetroEncabulatorFactorySingleton  avgt    4  209.823 ± 13.330  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        org.bogus.hokus.pokus.Clazz1  avgt    4   73.479 ±  4.820  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                        com.bogus.hokus.pokus.Clazz2  avgt    4   77.332 ±  7.192  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                      edu.bogus.hokus.pokus.a.Clazz3  avgt    4   90.165 ±  4.701  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                             de.bogus.hokus.b.Clazz4  avgt    4   70.995 ±  2.363  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                   jp.bogus.c.Clazz5  avgt    4   53.924 ±  0.488  ns/op
NamePatternConverterBenchmark.benchNamePatternConverter                                                                                         cn.d.Clazz6  avgt    4   39.785 ±  0.219  ns/op

Conclusion

@schlosna you are correct, jdk16 shows substantially better performance using indexOf(char,int), the benchmark results align more closely with my original expectations as illustrated by the improvements abbreviating the longer RetroEncabulatorFactorySingleton class. The original implementation performs best on very short class names, but I think those are fast enough that it doesn't make much difference either way.

carterkozak

comment created time in 6 hours

Pull request review commentpalantir/witchcraft-api

Improve idea plugin description, move static config pieces to plugin.xml

 <idea-plugin url="https://github.com/palantir/witchcraft-api">     <id>com.palantir.witchcraft.api.logging.idea</id>     <name>Witchcraft Logging</name>-    <version>0.0.0</version>+    <description>Automatically renders witchcraft-logging-api structured log events from the idea console into color-coded human-readable text.</description>

emphasis on 'automatic' rather than 'render' so it's clear there's no button you have to click to make it work.

carterkozak

comment created time in 6 hours

PullRequestReviewEvent

PR opened palantir/witchcraft-api

Reviewers
Improve idea plugin description, move static config pieces to plugin.xml autorelease merge when ready no changelog
+1 -2

0 comment

2 changed files

pr created time in 6 hours

create barnchpalantir/witchcraft-api

branch : ckozak/better_description

created branch time in 6 hours

create barnchpalantir/witchcraft-api

branch : idea_plugin

created branch time in 6 hours

PullRequestReviewEvent

Pull request review commentapache/logging-log4j2

Improve worst-case NameAbbreviator performance

 public PatternAbbreviatorFragment(         /**          * Abbreviate element of name.          *-         * @param buf      buffer to receive element.-         * @param startPos starting index of name element.-         * @return starting index of next element.+         * @param input      input string which is being written to the output {@code buf}.+         * @param inputIndex starting index of name element in the {@code input} string.+         * @param buf        buffer to receive element.+         * @return starting  index of next element.          */-        public int abbreviate(final StringBuilder buf, final int startPos) {-            final int start = (startPos < 0) ? 0 : startPos;-            final int max = buf.length();-            int nextDot = -1;-            for (int i = start; i < max; i++) {-                if (buf.charAt(i) == '.') {-                    nextDot = i;-                    break;-                }+        int abbreviate(final String input, final int inputIndex, final StringBuilder buf) {+            // ckozak: indexOf with a string is intentional. indexOf(String, int) appears to+            // have optimizations that don't apply to indexOf(char, int)+            // which result in a >10% performance improvement in some+            // NamePatternConverterBenchmark cases. This should be re-evaluated with+            // future java releases.+            int nextDot = input.indexOf(".", inputIndex);

Great find! I really appreciate your insight, @schlosna. I'll a/b test on jdk16 to see how performance is impacted. If the character search is much better, it might be worthwhile to use that as it should stand the test of time, especially with jdk17 right around the corner.

carterkozak

comment created time in 8 hours

pull request commentpalantir/witchcraft-api

Implement the Witchcraft Logging API Idea plugin

Publish credentials are up.

carterkozak

comment created time in a day

push eventpalantir/witchcraft-api

Carter Kozak

commit sha e327b652c1aa3e78157e1a694769de93cdda465e

depends on the platform

view details

push time in a day

push eventpalantir/witchcraft-api

Carter Kozak

commit sha 563ebf6052899a32553636b0a8af5e1c3e3e4f24

defensive check

view details

push time in a day

create barnchpalantir/witchcraft-api

branch : idea_plugin

created branch time in a day

Pull request review commentapache/logging-log4j2

LOG4J2-2785: Added support for pattern Layout to abbreviate logger or class names except n rightmost words

 public void abbreviate(final String original, final StringBuilder destination) {             }         }     }++    /**+     * <p>Specialized abbreviator that shortens all words to the first char except the indicated number of rightmost words.+     * To select this abbreviator, use pattern <code>1.n*</code> where n (&gt; 0) is the number of rightmost words to leave unchanged.</p>+     *+     * By example for input <code>org.apache.logging.log4j.core.pattern.NameAbbreviator</code>:+     * <pre>+     * 1.1*     =&gt;   o.a.l.l.c.p.NameAbbreviator+     * 1.2*     =&gt;   o.a.l.l.c.pattern.NameAbbreviator+     * 1.3*     =&gt;   o.a.l.l.core.pattern.NameAbbreviator+     * ..+     * 1.999*   =&gt;   org.apache.logging.log4j.core.pattern.NameAbbreviator+     * </pre>+     * @since 2.x+     */+    static class DynamicWordAbbreviator extends NameAbbreviator {++        /** Right-most number of words (at least one) that will not be abbreviated. */+        private final int rightWordCount;++        static DynamicWordAbbreviator create(String pattern) {+            if (pattern != null) {+                Matcher matcher = Pattern.compile("1\\.([1-9][0-9]*)\\*").matcher(pattern);+                if (matcher.matches()) {+                    return new DynamicWordAbbreviator(Integer.parseInt(matcher.group(1)));+                }+            }+            return null;+        }++        private DynamicWordAbbreviator(int rightWordCount) {+            this.rightWordCount = rightWordCount;+        }++        @Override+        public void abbreviate(String original, StringBuilder destination) {+            if (original != null && destination != null) {+                String[] words = original.split("\\.");+                for (int i = 0; i < words.length - rightWordCount; i++) {+                    words[i] = words[i].substring(0, 1);

Probably worthwhile to add test coverage for an input string along the lines of org..example.Name with two periods in a row, I think this substring will throw an IndexOutOfBoundsException in that case.

sman-81

comment created time in a day

PullRequestReviewEvent

Pull request review commentapache/logging-log4j2

LOG4J2-2785: Added support for pattern Layout to abbreviate logger or class names except n rightmost words

 public void abbreviate(final String original, final StringBuilder destination) {             }         }     }++    /**+     * <p>Specialized abbreviator that shortens all words to the first char except the indicated number of rightmost words.+     * To select this abbreviator, use pattern <code>1.n*</code> where n (&gt; 0) is the number of rightmost words to leave unchanged.</p>+     *+     * By example for input <code>org.apache.logging.log4j.core.pattern.NameAbbreviator</code>:+     * <pre>+     * 1.1*     =&gt;   o.a.l.l.c.p.NameAbbreviator+     * 1.2*     =&gt;   o.a.l.l.c.pattern.NameAbbreviator+     * 1.3*     =&gt;   o.a.l.l.core.pattern.NameAbbreviator+     * ..+     * 1.999*   =&gt;   org.apache.logging.log4j.core.pattern.NameAbbreviator+     * </pre>+     * @since 2.x+     */+    static class DynamicWordAbbreviator extends NameAbbreviator {++        /** Right-most number of words (at least one) that will not be abbreviated. */+        private final int rightWordCount;++        static DynamicWordAbbreviator create(String pattern) {+            if (pattern != null) {+                Matcher matcher = Pattern.compile("1\\.([1-9][0-9]*)\\*").matcher(pattern);+                if (matcher.matches()) {+                    return new DynamicWordAbbreviator(Integer.parseInt(matcher.group(1)));+                }+            }+            return null;+        }++        private DynamicWordAbbreviator(int rightWordCount) {+            this.rightWordCount = rightWordCount;+        }++        @Override+        public void abbreviate(String original, StringBuilder destination) {+            if (original != null && destination != null) {+                String[] words = original.split("\\.");+                for (int i = 0; i < words.length - rightWordCount; i++) {+                    words[i] = words[i].substring(0, 1);+                }+                destination.append(String.join(".", words));

This looks very expensive. String.split uses regex and allocates a new string for each segment. Substring allocates another string per abbreviated segment, and the final String.join creates a string representation of the data that's added to the StringBuilder. I think allocation can be entirely avoided here by tacking indexes, and writing directly to the Destination buffer.

It could be interesting to run the benchmarks comparing 1.1* to the existing 1.

sman-81

comment created time in a day

PullRequestReviewEvent