Skip to content

Commit cf02cf3

Browse files
committedSep 1, 2023
8315098: Improve URLEncodeDecode microbenchmark
Reviewed-by: ecaspole, dfuchs
1 parent c32e340 commit cf02cf3

File tree

1 file changed

+91
-28
lines changed

1 file changed

+91
-28
lines changed
 

‎test/micro/org/openjdk/bench/java/net/URLEncodeDecode.java

+91-28
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
import java.io.UnsupportedEncodingException;
3939
import java.net.URLDecoder;
40+
import java.nio.charset.StandardCharsets;
4041
import java.util.Random;
4142
import java.util.concurrent.TimeUnit;
4243

@@ -51,78 +52,140 @@
5152
@Fork(value = 3)
5253
public class URLEncodeDecode {
5354

54-
@Param("1024")
55-
public int count;
55+
private static final int COUNT = 1024;
5656

5757
@Param("1024")
5858
public int maxLength;
5959

60-
@Param("3")
61-
public long mySeed;
60+
/**
61+
* Percentage of strings that will remain unchanged by an encoding/decoding (0-100)
62+
*/
63+
@Param({"0", "75", "100"})
64+
public int unchanged;
65+
66+
/**
67+
* Percentage of chars in changed strings that cause encoding/decoding to happen (0-100)
68+
*/
69+
@Param({"6"})
70+
public int encodeChars;
6271

6372
public String[] testStringsEncode;
6473
public String[] testStringsDecode;
6574
public String[] toStrings;
6675

67-
@Setup
76+
@Setup()
6877
public void setupStrings() {
69-
char[] tokens = new char[((int) 'Z' - (int) 'A' + 1) + ((int) 'z' - (int) 'a' + 1) + ((int) '9' - (int) '1' + 1) + 5];
78+
char[] encodeTokens = new char[] { '[', '(', ' ', '\u00E4', '\u00E5', '\u00F6', ')', '='};
79+
char[] tokens = new char[('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1) + 4];
7080
int n = 0;
71-
tokens[n++] = '0';
72-
for (int i = (int) '1'; i <= (int) '9'; i++) {
73-
tokens[n++] = (char) i;
81+
for (char c = '0'; c <= '9'; c++) {
82+
tokens[n++] = c;
7483
}
75-
for (int i = (int) 'A'; i <= (int) 'Z'; i++) {
76-
tokens[n++] = (char) i;
84+
for (char c = 'A'; c <= 'Z'; c++) {
85+
tokens[n++] = c;
7786
}
78-
for (int i = (int) 'a'; i <= (int) '<'; i++) {
79-
tokens[n++] = (char) i;
87+
for (char c = 'a'; c <= 'z'; c++) {
88+
tokens[n++] = c;
8089
}
8190
tokens[n++] = '-';
8291
tokens[n++] = '_';
8392
tokens[n++] = '.';
84-
tokens[n++] = '*';
93+
tokens[n] = '*';
8594

86-
Random r = new Random(mySeed);
87-
testStringsEncode = new String[count];
88-
testStringsDecode = new String[count];
89-
toStrings = new String[count];
90-
for (int i = 0; i < count; i++) {
95+
Random r = new Random(3);
96+
testStringsEncode = new String[COUNT];
97+
testStringsDecode = new String[COUNT];
98+
toStrings = new String[COUNT];
99+
for (int i = 0; i < COUNT; i++) {
91100
int l = r.nextInt(maxLength);
101+
boolean needEncoding = r.nextInt(100) >= unchanged;
92102
StringBuilder sb = new StringBuilder();
103+
boolean hasEncoded = false;
93104
for (int j = 0; j < l; j++) {
94-
int c = r.nextInt(tokens.length);
95-
sb.append(tokens[c]);
105+
if (needEncoding && r.nextInt(100) < encodeChars) {
106+
addToken(encodeTokens, r, sb);
107+
hasEncoded = true;
108+
} else {
109+
addToken(tokens, r, sb);
110+
}
111+
}
112+
if (needEncoding && !hasEncoded) {
113+
addToken(encodeTokens, r, sb);
96114
}
97115
testStringsEncode[i] = sb.toString();
98116
}
117+
int countUnchanged = 0;
118+
for (String s : testStringsEncode) {
119+
if (s.equals(java.net.URLEncoder.encode(s, StandardCharsets.UTF_8))) {
120+
countUnchanged++;
121+
} else {
122+
if (unchanged == 100) {
123+
System.out.println("Unexpectedly needs encoding action: ");
124+
System.out.println("\t" + s);
125+
System.out.println("\t" + java.net.URLEncoder.encode(s, StandardCharsets.UTF_8));
126+
}
127+
}
128+
}
129+
System.out.println();
130+
System.out.println("Generated " + testStringsEncode.length + " encodable strings, " + countUnchanged + " of which does not need encoding action");
99131

100-
for (int i = 0; i < count; i++) {
132+
for (int i = 0; i < COUNT; i++) {
101133
int l = r.nextInt(maxLength);
134+
boolean needDecoding = r.nextInt(100) >= unchanged;
102135
StringBuilder sb = new StringBuilder();
136+
boolean hasDecoded = false;
103137
for (int j = 0; j < l; j++) {
104-
int c = r.nextInt(tokens.length + 5);
105-
if (c >= tokens.length) {
106-
sb.append("%").append(tokens[r.nextInt(16)]).append(tokens[r.nextInt(16)]);
138+
if (needDecoding && r.nextInt(100) < encodeChars) {
139+
addDecodableChar(tokens, r, sb);
140+
hasDecoded = true;
107141
} else {
108-
sb.append(tokens[c]);
142+
addToken(tokens, r, sb);
109143
}
110144
}
145+
if (needDecoding && !hasDecoded) {
146+
addDecodableChar(tokens, r, sb);
147+
}
111148
testStringsDecode[i] = sb.toString();
112149
}
150+
countUnchanged = 0;
151+
for (String s : testStringsDecode) {
152+
if (s.equals(java.net.URLDecoder.decode(s, StandardCharsets.UTF_8))) {
153+
countUnchanged++;
154+
} else {
155+
if (unchanged == 100) {
156+
System.out.println("Unexpectedly needs encoding action: ");
157+
System.out.println("\t" + s);
158+
System.out.println("\t" + java.net.URLDecoder.decode(s, StandardCharsets.UTF_8));
159+
}
160+
}
161+
}
162+
System.out.println("Generated " + testStringsDecode.length + " decodable strings, " + countUnchanged + " of which does not need decoding action");
163+
}
164+
165+
private static void addToken(char[] tokens, Random r, StringBuilder sb) {
166+
int c = r.nextInt(tokens.length);
167+
sb.append(tokens[c]);
168+
}
169+
170+
private static void addDecodableChar(char[] tokens, Random r, StringBuilder sb) {
171+
if (r.nextInt(100) < 15) {
172+
sb.append('+'); // exercise '+' -> ' ' decoding paths.
173+
} else {
174+
sb.append("%").append(tokens[r.nextInt(16)]).append(tokens[r.nextInt(16)]);
175+
}
113176
}
114177

115178
@Benchmark
116179
public void testEncodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
117180
for (String s : testStringsEncode) {
118-
bh.consume(java.net.URLEncoder.encode(s, "UTF-8"));
181+
bh.consume(java.net.URLEncoder.encode(s, StandardCharsets.UTF_8));
119182
}
120183
}
121184

122185
@Benchmark
123186
public void testDecodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
124187
for (String s : testStringsDecode) {
125-
bh.consume(URLDecoder.decode(s, "UTF-8"));
188+
bh.consume(URLDecoder.decode(s, StandardCharsets.UTF_8));
126189
}
127190
}
128191

0 commit comments

Comments
 (0)
Please sign in to comment.