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

ICU-23061: LowercaseTransliterator has poor scalability due to synchronized state #3417

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ public Transliterator getInstance(String ID) {
private final ULocale locale;

private final UCaseProps csp;
private ReplaceableContextIterator iter;
private StringBuilder result;
private int caseLocale;

/**
Expand All @@ -54,16 +52,14 @@ public LowercaseTransliterator(ULocale loc) {
super(_ID, null);
locale = loc;
csp=UCaseProps.INSTANCE;
iter=new ReplaceableContextIterator();
result = new StringBuilder();
caseLocale = UCaseProps.getCaseLocale(locale);
}

/**
* Implements {@link Transliterator#handleTransliterate}.
*/
@Override
protected synchronized void handleTransliterate(Replaceable text,
protected void handleTransliterate(Replaceable text,
Position offsets, boolean isIncremental) {
if(csp==null) {
return;
Expand All @@ -73,8 +69,10 @@ protected synchronized void handleTransliterate(Replaceable text,
return;
}

ReplaceableContextIterator iter = new ReplaceableContextIterator();
StringBuilder result = new StringBuilder();

iter.setText(text);
result.setLength(0);
int c, delta;

// Walk through original string
Expand Down
3 changes: 3 additions & 0 deletions icu4j/perf-tests/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ COLLATION TESTS
The collation tests run only on the command line with tabular output:
perl collationperf.pl |& tee collation_output.txt

JMH
Some performance tests run using OpenJDK JMH. These may be launched with:
java -jar perf-tests/target/jmh-benchmarks.jar

OTHER COMMAND LINE TESTS
Additional tests are run from the command line, each producing an HTML
Expand Down
57 changes: 56 additions & 1 deletion icu4j/perf-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<properties>
<module-name>perf_tests</module-name>
<jmh.version>1.37</jmh.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -43,12 +44,23 @@
<artifactId>commons-cli</artifactId>
<version>${commons-cli.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<!-- Copy dependencies by default, so that everythign is easier to run
<!-- Copy dependencies by default, so that everything is easier to run
without having to explicitly list all kind of folders in classpath.
Just use `./target/*` and `./target/dependency/*`
-->
Expand All @@ -63,6 +75,49 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessors>
<annotationProcessor>org.openjdk.jmh.generators.BenchmarkProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>jmh-benchmarks</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
<filters>
<filter>
<!-- Shading signed JARs will fail without this.
http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
-->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ibm.icu.dev.test.perf;

import java.util.concurrent.TimeUnit;

import com.ibm.icu.text.Transliterator;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class LowercaseTransliteratorPerf {

static final Transliterator LOWER = Transliterator.getInstance("Lower");

@Benchmark
public String testShort() {
return LOWER.transliterate("Cat");
}

@Benchmark
public String testSentence() {
return LOWER.transliterate("The Quick Brown Fox Jumped Over The Lazy Dog");
}

}