Skip to content

Commit 17f04fc

Browse files
author
Andrew Haley
committed
8254078: DataOutputStream is very slow post-disabling of Biased Locking
Reviewed-by: rriggs, shade, alanb
1 parent 79b7909 commit 17f04fc

File tree

3 files changed

+143
-11
lines changed

3 files changed

+143
-11
lines changed

src/java.base/share/classes/java/io/DataInputStream.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@
3333
* way. An application uses a data output stream to write data that
3434
* can later be read by a data input stream.
3535
* <p>
36-
* DataInputStream is not necessarily safe for multithreaded access.
37-
* Thread safety is optional and is the responsibility of users of
38-
* methods in this class.
36+
* A DataInputStream is not safe for use by multiple concurrent
37+
* threads. If a DataInputStream is to be used by more than one
38+
* thread then access to the data input stream should be controlled
39+
* by appropriate synchronization.
3940
*
4041
* @author Arthur van Hoff
4142
* @see java.io.DataOutputStream

src/java.base/share/classes/java/io/DataOutputStream.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
* A data output stream lets an application write primitive Java data
3030
* types to an output stream in a portable way. An application can
3131
* then use a data input stream to read the data back in.
32+
* <p>
33+
* A DataOutputStream is not safe for use by multiple concurrent
34+
* threads. If a DataOutputStream is to be used by more than one
35+
* thread then access to the data output stream should be controlled
36+
* by appropriate synchronization.
3237
*
3338
* @see java.io.DataInputStream
3439
* @since 1.0
@@ -162,8 +167,9 @@ public final void writeByte(int v) throws IOException {
162167
* @see java.io.FilterOutputStream#out
163168
*/
164169
public final void writeShort(int v) throws IOException {
165-
out.write((v >>> 8) & 0xFF);
166-
out.write((v >>> 0) & 0xFF);
170+
writeBuffer[0] = (byte)(v >>> 8);
171+
writeBuffer[1] = (byte)(v >>> 0);
172+
out.write(writeBuffer, 0, 2);
167173
incCount(2);
168174
}
169175

@@ -177,8 +183,9 @@ public final void writeShort(int v) throws IOException {
177183
* @see java.io.FilterOutputStream#out
178184
*/
179185
public final void writeChar(int v) throws IOException {
180-
out.write((v >>> 8) & 0xFF);
181-
out.write((v >>> 0) & 0xFF);
186+
writeBuffer[0] = (byte)(v >>> 8);
187+
writeBuffer[1] = (byte)(v >>> 0);
188+
out.write(writeBuffer, 0, 2);
182189
incCount(2);
183190
}
184191

@@ -192,10 +199,11 @@ public final void writeChar(int v) throws IOException {
192199
* @see java.io.FilterOutputStream#out
193200
*/
194201
public final void writeInt(int v) throws IOException {
195-
out.write((v >>> 24) & 0xFF);
196-
out.write((v >>> 16) & 0xFF);
197-
out.write((v >>> 8) & 0xFF);
198-
out.write((v >>> 0) & 0xFF);
202+
writeBuffer[0] = (byte)(v >>> 24);
203+
writeBuffer[1] = (byte)(v >>> 16);
204+
writeBuffer[2] = (byte)(v >>> 8);
205+
writeBuffer[3] = (byte)(v >>> 0);
206+
out.write(writeBuffer, 0, 4);
199207
incCount(4);
200208
}
201209

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright (c) 2020, Red Hat Inc. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package org.openjdk.bench.java.io;
25+
26+
import org.openjdk.jmh.annotations.*;
27+
28+
import java.io.*;
29+
import java.util.concurrent.TimeUnit;
30+
31+
@BenchmarkMode(Mode.AverageTime)
32+
@OutputTimeUnit(TimeUnit.MICROSECONDS)
33+
@Fork(value = 1, warmups = 0)
34+
@Measurement(iterations = 6, time = 1)
35+
@Warmup(iterations=2, time = 2)
36+
@State(Scope.Benchmark)
37+
public class DataOutputStreamTest {
38+
39+
public enum BasicType {CHAR, SHORT, INT, STRING}
40+
@Param({"CHAR", "SHORT", "INT", /* "STRING"*/}) BasicType basicType;
41+
42+
@Param({"4096"}) int size;
43+
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(size);
44+
File f;
45+
String outputString;
46+
FileOutputStream fileOutputStream;
47+
DataOutput bufferedFileStream, rawFileStream, byteArrayStream;
48+
49+
@Setup(Level.Trial)
50+
public void setup() throws Exception {
51+
f = File.createTempFile("DataOutputStreamTest","out");
52+
fileOutputStream = new FileOutputStream(f);
53+
byteArrayStream = new DataOutputStream(byteArrayOutputStream);
54+
rawFileStream = new DataOutputStream(fileOutputStream);
55+
bufferedFileStream = new DataOutputStream(new BufferedOutputStream(fileOutputStream));
56+
outputString = new String(new byte[size]);
57+
}
58+
59+
public void writeChars(DataOutput dataOutput)
60+
throws Exception {
61+
for (int i = 0; i < size; i += 2) {
62+
dataOutput.writeChar(i);
63+
}
64+
}
65+
66+
public void writeShorts(DataOutput dataOutput)
67+
throws Exception {
68+
for (int i = 0; i < size; i += 2) {
69+
dataOutput.writeShort(i);
70+
}
71+
}
72+
73+
public void writeInts(DataOutput dataOutput)
74+
throws Exception {
75+
for (int i = 0; i < size; i += 4) {
76+
dataOutput.writeInt(i);
77+
}
78+
}
79+
80+
public void writeString(DataOutput dataOutput)
81+
throws Exception {
82+
dataOutput.writeChars(outputString);
83+
}
84+
85+
public void write(DataOutput dataOutput)
86+
throws Exception {
87+
switch (basicType) {
88+
case CHAR:
89+
writeChars(dataOutput);
90+
break;
91+
case SHORT:
92+
writeShorts(dataOutput);
93+
break;
94+
case INT:
95+
writeInts(dataOutput);
96+
break;
97+
case STRING:
98+
writeString(dataOutput);
99+
break;
100+
}
101+
}
102+
103+
@Benchmark
104+
public void dataOutputStreamOverByteArray() throws Exception {
105+
byteArrayOutputStream.reset();
106+
write(byteArrayStream);
107+
byteArrayOutputStream.flush();
108+
}
109+
110+
@Benchmark
111+
public void dataOutputStreamOverRawFileStream() throws Exception {
112+
fileOutputStream.getChannel().position(0);
113+
write(rawFileStream);
114+
fileOutputStream.flush();
115+
}
116+
117+
@Benchmark
118+
public void dataOutputStreamOverBufferedFileStream() throws Exception{
119+
fileOutputStream.getChannel().position(0);
120+
write(bufferedFileStream);
121+
fileOutputStream.flush();
122+
}
123+
}

0 commit comments

Comments
 (0)