Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8279833: Loop optimization issue in String.encodeUTF8_UTF16
Reviewed-by: shade, alanb
  • Loading branch information
cl4es committed Jan 11, 2022
1 parent 9e02447 commit c3d0a94
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 43 deletions.
11 changes: 7 additions & 4 deletions src/java.base/share/classes/java/lang/String.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1284,14 +1284,17 @@ private static byte[] encodeUTF8_UTF16(byte[] val, boolean doReplace) {
int sp = 0;
int sl = val.length >> 1;
byte[] dst = new byte[sl * 3];
char c;
while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') {
while (sp < sl) {
// ascii fast loop;
char c = StringUTF16.getChar(val, sp);
if (c >= '\u0080') {
break;
}
dst[dp++] = (byte)c;
sp++;
}
while (sp < sl) {
c = StringUTF16.getChar(val, sp++);
char c = StringUTF16.getChar(val, sp++);
if (c < 0x80) {
dst[dp++] = (byte)c;
} else if (c < 0x800) {
Expand Down
116 changes: 77 additions & 39 deletions test/micro/org/openjdk/bench/java/lang/StringEncode.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -30,59 +30,97 @@

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(value = 3, jvmArgs = "-Xmx1g")
@Fork(value = 3)
@Warmup(iterations = 5, time = 2)
@Measurement(iterations = 5, time = 3)
@State(Scope.Thread)
public class StringEncode {

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(value = 3, jvmArgs = "-Xmx1g")
@Warmup(iterations = 5, time = 2)
@Measurement(iterations = 5, time = 2)
@State(Scope.Thread)
public static class WithCharset {
@Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6"})
private String charsetName;
private Charset charset;
private String asciiString;
private String utf16String;
private String longUtf16String;
private String longUtf16StartString;

@Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6"})
private String charsetName;
@Setup
public void setup() {
charset = Charset.forName(charsetName);
asciiString = "ascii string";
utf16String = "UTF-\uFF11\uFF16 string";
longUtf16String = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac sem eu
urna egestas placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a.
Nulla nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et
sapien in magna porta ultricies. Sed vel pellentesque nibh. Pellentesque dictum
dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent
per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla
sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida
efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet.
Suspendisse potenti.
private Charset charset;
private String asciiString;
private String utf16String;
Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis
nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet
sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum
consectetur eget non tortor. Praesent bibendum vel felis nec dignissim.
Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id
hendrerit sapien. Donec aliquam mattis lectus eu ultrices. Duis eu nisl
euismod, blandit mauris vel, placerat urna. Etiam malesuada enim purus,
tristique mollis odio blandit quis. Vivamus posuere.
\uFF11
""";
longUtf16StartString = """
\uFF11
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac sem eu
urna egestas placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a.
Nulla nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et
sapien in magna porta ultricies. Sed vel pellentesque nibh. Pellentesque dictum
dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent
per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla
sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida
efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet.
Suspendisse potenti.
@Setup
public void setup() {
charset = Charset.forName(charsetName);
asciiString = "ascii string";
utf16String = "UTF-\uFF11\uFF16 string";
}
Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis
nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet
sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum
consectetur eget non tortor. Praesent bibendum vel felis nec dignissim.
Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id
hendrerit sapien. Donec aliquam mattis lectus eu ultrices. Duis eu nisl
euismod, blandit mauris vel, placerat urna. Etiam malesuada enim purus,
tristique mollis odio blandit quis. Vivamus posuere.
""";
}

@Benchmark
public void encodeCharsetName(Blackhole bh) throws Exception {
bh.consume(asciiString.getBytes(charsetName));
bh.consume(utf16String.getBytes(charsetName));
}
@Benchmark
public byte[] encodeAsciiCharsetName() throws Exception {
return asciiString.getBytes(charset);
}

@Benchmark
public byte[] encodeAscii() throws Exception {
return asciiString.getBytes(charset);
}

@Benchmark
public void encodeCharset(Blackhole bh) throws Exception {
bh.consume(asciiString.getBytes(charset));
bh.consume(utf16String.getBytes(charset));
}
@Benchmark
public void encodeMix(Blackhole bh) throws Exception {
bh.consume(asciiString.getBytes(charset));
bh.consume(utf16String.getBytes(charset));
}

private String asciiDefaultString;
private String utf16DefaultString;
@Benchmark
public byte[] encodeUTF16LongEnd() throws Exception {
return longUtf16String.getBytes(charset);
}

@Setup
public void setup() {
asciiDefaultString = "ascii string";
utf16DefaultString = "UTF-\uFF11\uFF16 string";
@Benchmark
public byte[] encodeUTF16LongStart() throws Exception {
return longUtf16StartString.getBytes(charset);
}

@Benchmark
public void encodeDefault(Blackhole bh) throws Exception {
bh.consume(asciiDefaultString.getBytes());
bh.consume(utf16DefaultString.getBytes());
public byte[] encodeUTF16() throws Exception {
return utf16String.getBytes(charset);
}
}

3 comments on commit c3d0a94

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GoeLin
Copy link
Member

@GoeLin GoeLin commented on c3d0a94 Jan 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/backport jdk17u-dev

@openjdk
Copy link

@openjdk openjdk bot commented on c3d0a94 Jan 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GoeLin the backport was successfully created on the branch GoeLin-backport-c3d0a940 in my personal fork of openjdk/jdk17u-dev. To create a pull request with this backport targeting openjdk/jdk17u-dev:master, just click the following link:

➡️ Create pull request

The title of the pull request is automatically filled in correctly and below you find a suggestion for the pull request body:

Hi all,

This pull request contains a backport of commit c3d0a940 from the openjdk/jdk repository.

The commit being backported was authored by Claes Redestad on 11 Jan 2022 and was reviewed by Aleksey Shipilev and Alan Bateman.

Thanks!

If you need to update the source branch of the pull then run the following commands in a local clone of your personal fork of openjdk/jdk17u-dev:

$ git fetch https://github.com/openjdk-bots/jdk17u-dev GoeLin-backport-c3d0a940:GoeLin-backport-c3d0a940
$ git checkout GoeLin-backport-c3d0a940
# make changes
$ git add paths/to/changed/files
$ git commit --message 'Describe additional changes made'
$ git push https://github.com/openjdk-bots/jdk17u-dev GoeLin-backport-c3d0a940

Please sign in to comment.