undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Benchmark DatagramChannel send/receive.
|
||||
*/
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(3)
|
||||
public class DatagramChannelSendReceive {
|
||||
|
||||
private int counter = 0;
|
||||
|
||||
private ByteBuffer buf;
|
||||
private DatagramChannel channel1, channel2, connectedWriteChannel,
|
||||
connectedReadChannel, multipleReceiveChannel, multipleSendChannel;
|
||||
private DatagramChannel[] dca;
|
||||
|
||||
@Param({"128", "32768"})
|
||||
public int size;
|
||||
@Param({"4"})
|
||||
public int channelCount;
|
||||
@Param({"true"})
|
||||
public boolean useDirectBuffer;
|
||||
|
||||
@Setup
|
||||
public void setUp() throws IOException {
|
||||
buf = (useDirectBuffer) ? ByteBuffer.allocateDirect(size) :
|
||||
ByteBuffer.allocate(size);
|
||||
buf.clear();
|
||||
|
||||
InetSocketAddress addr =
|
||||
new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
|
||||
|
||||
// single send - same socket; different sockets
|
||||
channel1 = DatagramChannel.open().bind(addr);
|
||||
channel2 = DatagramChannel.open().bind(addr);
|
||||
|
||||
// connected read / write
|
||||
connectedWriteChannel = DatagramChannel.open().bind(addr);
|
||||
connectedReadChannel = DatagramChannel.open().bind(addr);
|
||||
connectedWriteChannel.connect(connectedReadChannel.getLocalAddress());
|
||||
connectedReadChannel.connect(connectedWriteChannel.getLocalAddress());
|
||||
|
||||
// multiple senders / multiple receivers
|
||||
dca = new DatagramChannel[channelCount];
|
||||
for (int i = 0; i < dca.length; i++) {
|
||||
dca[i] = DatagramChannel.open().bind(addr);
|
||||
}
|
||||
multipleReceiveChannel = DatagramChannel.open().bind(addr);
|
||||
multipleSendChannel = DatagramChannel.open().bind(addr);
|
||||
}
|
||||
|
||||
// same sender receiver
|
||||
@Benchmark
|
||||
public void sendReceiveSingleSocket() throws IOException {
|
||||
buf.clear();
|
||||
channel1.send(buf, channel1.getLocalAddress());
|
||||
buf.clear();
|
||||
channel1.receive(buf);
|
||||
}
|
||||
|
||||
// single sender, single receiver
|
||||
@Benchmark
|
||||
public void sendReceive() throws IOException {
|
||||
buf.clear();
|
||||
channel1.send(buf, channel2.getLocalAddress());
|
||||
buf.clear();
|
||||
channel2.receive(buf);
|
||||
}
|
||||
|
||||
// connected sender receiver
|
||||
@Benchmark
|
||||
public void sendReceiveConnected() throws IOException {
|
||||
buf.clear();
|
||||
connectedWriteChannel.write(buf);
|
||||
buf.clear();
|
||||
connectedReadChannel.read(buf);
|
||||
}
|
||||
|
||||
// multiple senders, single receiver
|
||||
@Benchmark
|
||||
public void sendMultiple() throws IOException {
|
||||
int i = counter;
|
||||
buf.clear();
|
||||
dca[i].send(buf, multipleReceiveChannel.getLocalAddress());
|
||||
buf.clear();
|
||||
multipleReceiveChannel.receive(buf);
|
||||
counter = ++i % dca.length;
|
||||
}
|
||||
|
||||
// single sender, multiple receivers
|
||||
@Benchmark
|
||||
public void receiveMultiple() throws IOException {
|
||||
int i = counter;
|
||||
buf.clear();
|
||||
multipleSendChannel.send(buf, dca[i].getLocalAddress());
|
||||
buf.clear();
|
||||
dca[i].receive(buf);
|
||||
counter = ++i % dca.length;
|
||||
}
|
||||
|
||||
@TearDown
|
||||
public void tearDown() throws IOException {
|
||||
channel1.close();
|
||||
channel2.close();
|
||||
connectedWriteChannel.close();
|
||||
connectedReadChannel.close();
|
||||
multipleReceiveChannel.close();
|
||||
multipleSendChannel.close();
|
||||
for (DatagramChannel dc : dca) {
|
||||
dc.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* Benchmark DatagramSocket send/receive.
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(3)
|
||||
public class DatagramSocketSendReceive {
|
||||
private int counter = 0;
|
||||
|
||||
private DatagramSocket socket1, socket2, connectedSendSocket,
|
||||
connectedReceiveSocket, multipleRecieveSocket, multipleSendSocket;
|
||||
private DatagramPacket sendPkt1, sendPkt2, connectedSendPkt, multipleSendPkt,
|
||||
receivePkt;
|
||||
|
||||
private DatagramSocket[] dsa;
|
||||
private DatagramPacket[] pkts;
|
||||
|
||||
@Param({"128", "32768"})
|
||||
public int size;
|
||||
|
||||
@Param({"4"})
|
||||
public int socketCount;
|
||||
|
||||
@Setup
|
||||
public void setUp() throws IOException {
|
||||
byte[] buf = new byte[size];
|
||||
InetAddress addr = InetAddress.getLocalHost();
|
||||
|
||||
receivePkt = new DatagramPacket(buf, buf.length);
|
||||
|
||||
// single send - same socket; different sockets
|
||||
socket1 = new DatagramSocket(0, addr);
|
||||
socket2 = new DatagramSocket(0, addr);
|
||||
sendPkt1 = new DatagramPacket(buf, buf.length, addr,
|
||||
socket1.getLocalPort());
|
||||
sendPkt2 = new DatagramPacket(buf, buf.length, addr,
|
||||
socket2.getLocalPort());
|
||||
|
||||
// connected send/receive
|
||||
connectedSendSocket = new DatagramSocket(0, addr);
|
||||
connectedReceiveSocket = new DatagramSocket(0, addr);
|
||||
connectedSendSocket.connect(addr, connectedReceiveSocket.getLocalPort());
|
||||
connectedReceiveSocket.connect(addr, connectedSendSocket.getLocalPort());
|
||||
connectedSendPkt = new DatagramPacket(buf, buf.length);
|
||||
|
||||
// multiple senders / multiple receivers
|
||||
dsa = new DatagramSocket[socketCount];
|
||||
pkts = new DatagramPacket[socketCount];
|
||||
for (int i = 0; i < dsa.length; i++) {
|
||||
dsa[i] = new DatagramSocket(0, addr);
|
||||
pkts[i] = new DatagramPacket(buf, buf.length,
|
||||
addr, dsa[i].getLocalPort());
|
||||
}
|
||||
multipleRecieveSocket = new DatagramSocket(0, addr);
|
||||
multipleSendSocket = new DatagramSocket(0, addr);
|
||||
multipleSendPkt = new DatagramPacket(buf, buf.length, addr,
|
||||
multipleRecieveSocket.getLocalPort());
|
||||
}
|
||||
|
||||
// same sender receiver
|
||||
@Benchmark
|
||||
public void sendReceiveSingleSocket() throws IOException {
|
||||
socket1.send(sendPkt1);
|
||||
socket1.receive(receivePkt);
|
||||
}
|
||||
|
||||
// single sender, single receiver
|
||||
@Benchmark
|
||||
public void sendReceive() throws IOException {
|
||||
socket1.send(sendPkt2);
|
||||
socket2.receive(receivePkt);
|
||||
}
|
||||
|
||||
// connected sender receiver
|
||||
@Benchmark
|
||||
public void sendReceiveConnected() throws IOException {
|
||||
connectedSendSocket.send(connectedSendPkt);
|
||||
connectedReceiveSocket.receive(receivePkt);
|
||||
}
|
||||
|
||||
// multiple senders, single receiver
|
||||
@Benchmark
|
||||
public void sendMultiple() throws IOException {
|
||||
int i = counter;
|
||||
dsa[i].send(multipleSendPkt);
|
||||
multipleRecieveSocket.receive(receivePkt);
|
||||
counter = ++i % dsa.length;
|
||||
}
|
||||
|
||||
// single sender, multiple receivers
|
||||
@Benchmark
|
||||
public void receiveMultiple() throws IOException {
|
||||
int i = counter;
|
||||
multipleSendSocket.send(pkts[i]);
|
||||
dsa[i].receive(receivePkt);
|
||||
counter = ++i % dsa.length;
|
||||
}
|
||||
|
||||
@TearDown
|
||||
public void tearDown() {
|
||||
socket1.close();
|
||||
socket2.close();
|
||||
connectedSendSocket.close();
|
||||
connectedReceiveSocket.close();
|
||||
|
||||
multipleRecieveSocket.close();
|
||||
multipleSendSocket.close();
|
||||
for (DatagramSocket ds : dsa) {
|
||||
ds.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2024, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Assess time to perform native NetworkInterface lookups; uses
|
||||
* reflection to access both package-private isBoundInetAddress and
|
||||
* public getByInetAddress (to get comparable numbers)
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Fork(value = 2, jvmArgs = "--add-opens=java.base/java.net=ALL-UNNAMED")
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
public class NetworkInterfaceLookup {
|
||||
|
||||
static final InetAddress address = InetAddress.getLoopbackAddress();
|
||||
|
||||
static final Method isBoundInetAddress_method;
|
||||
|
||||
static final Method getByInetAddress_method;
|
||||
|
||||
static {
|
||||
Method isBound = null;
|
||||
Method getByInet = null;
|
||||
|
||||
try {
|
||||
isBound = NetworkInterface.class.getDeclaredMethod("isBoundInetAddress", InetAddress.class);
|
||||
isBound.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
System.out.println("NetworkInterface.isBoundInetAddress not found");
|
||||
}
|
||||
|
||||
try {
|
||||
getByInet = NetworkInterface.class.getDeclaredMethod("getByInetAddress", InetAddress.class);
|
||||
} catch (Exception e) {
|
||||
System.out.println("NetworkInterface.getByInetAddress not found");
|
||||
}
|
||||
isBoundInetAddress_method = isBound;
|
||||
getByInetAddress_method = getByInet;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public boolean bound() throws Exception {
|
||||
return (boolean)isBoundInetAddress_method.invoke(null, address);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NetworkInterface getByInetAddress() throws Exception {
|
||||
return (NetworkInterface)getByInetAddress_method.invoke(null, address);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2025, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.StandardProtocolFamily;
|
||||
import java.net.UnixDomainSocketAddress;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.RunnerException;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
/**
|
||||
* Measures connection setup times
|
||||
*/
|
||||
@BenchmarkMode(Mode.SingleShotTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 3)
|
||||
public class SocketChannelConnectionSetup {
|
||||
|
||||
private ServerSocketChannel ssc;
|
||||
|
||||
private Path sscFilePath;
|
||||
|
||||
private SocketChannel s1, s2;
|
||||
|
||||
@Param({"INET", "UNIX"})
|
||||
private String family;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void beforeRun() throws IOException {
|
||||
StandardProtocolFamily typedFamily = StandardProtocolFamily.valueOf(family);
|
||||
ssc = ServerSocketChannel.open(typedFamily).bind(null);
|
||||
// Record the UDS file path right after binding, as the socket may be
|
||||
// closed later due to a failure, and subsequent calls to `getPath()`
|
||||
// will throw.
|
||||
sscFilePath = ssc.getLocalAddress() instanceof UnixDomainSocketAddress udsChannel
|
||||
? udsChannel.getPath()
|
||||
: null;
|
||||
}
|
||||
|
||||
@TearDown(Level.Trial)
|
||||
public void afterRun() throws Exception {
|
||||
ssc.close();
|
||||
if (sscFilePath != null) {
|
||||
Files.delete(sscFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@Measurement(iterations = 5, batchSize=200)
|
||||
public void test() throws IOException {
|
||||
s1 = SocketChannel.open(ssc.getLocalAddress());
|
||||
s2 = ssc.accept();
|
||||
s1.close();
|
||||
s2.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws RunnerException {
|
||||
Options opt = new OptionsBuilder()
|
||||
.include(org.openjdk.bench.java.net.SocketChannelConnectionSetup.class.getSimpleName())
|
||||
.warmupForks(1)
|
||||
.forks(2)
|
||||
.build();
|
||||
|
||||
new Runner(opt).run();
|
||||
|
||||
opt = new OptionsBuilder()
|
||||
.include(org.openjdk.bench.java.net.SocketChannelConnectionSetup.class.getSimpleName())
|
||||
.jvmArgs("-Djdk.net.useFastTcpLoopback=true")
|
||||
.warmupForks(1)
|
||||
.forks(2)
|
||||
.build();
|
||||
|
||||
new Runner(opt).run();
|
||||
}
|
||||
}
|
||||
167
test/micro/org/openjdk/bench/java/net/SocketEventOverhead.java
Normal file
167
test/micro/org/openjdk/bench/java/net/SocketEventOverhead.java
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 2025, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import jdk.internal.event.SocketReadEvent;
|
||||
import jdk.internal.event.SocketWriteEvent;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Test the overhead of the handling jfr events SocketReadEvent and
|
||||
* SocketWriteEvent without the latencies of the actual I/O code.
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
|
||||
@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
|
||||
@State(Scope.Thread)
|
||||
public class SocketEventOverhead {
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports",
|
||||
"java.base/jdk.internal.event=ALL-UNNAMED" })
|
||||
@Benchmark
|
||||
public int socketWriteJFRDisabled(SkeletonFixture fixture) {
|
||||
return fixture.write();
|
||||
}
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports",
|
||||
"java.base/jdk.internal.event=ALL-UNNAMED",
|
||||
"-XX:StartFlightRecording:jdk.SocketWrite#enabled=false"})
|
||||
@Benchmark
|
||||
public int socketWriteJFREnabledEventDisabled(SkeletonFixture fixture) {
|
||||
return fixture.write();
|
||||
}
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports",
|
||||
"java.base/jdk.internal.event=ALL-UNNAMED",
|
||||
"-XX:StartFlightRecording:jdk.SocketWrite#enabled=true,jdk.SocketWrite#threshold=1s,jdk.SocketWrite#throttle=off"})
|
||||
@Benchmark
|
||||
public int socketWriteJFREnabledEventNotEmitted(SkeletonFixture fixture) {
|
||||
return fixture.write();
|
||||
}
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports","java.base/jdk.internal.event=ALL-UNNAMED",
|
||||
"-XX:StartFlightRecording:jdk.SocketWrite#enabled=true,jdk.SocketWrite#threshold=0ms,disk=false,jdk.SocketWrite#stackTrace=false,jdk.SocketWrite#throttle=off"})
|
||||
@Benchmark
|
||||
public int socketWriteJFREnabledEventEmitted(SkeletonFixture fixture) {
|
||||
return fixture.write();
|
||||
}
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports",
|
||||
"java.base/jdk.internal.event=ALL-UNNAMED" })
|
||||
@Benchmark
|
||||
public int socketReadJFRDisabled(SkeletonFixture fixture) {
|
||||
return fixture.read();
|
||||
}
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports",
|
||||
"java.base/jdk.internal.event=ALL-UNNAMED",
|
||||
"-XX:StartFlightRecording:jdk.SocketRead#enabled=false"})
|
||||
@Benchmark
|
||||
public int socketReadJFREnabledEventDisabled(SkeletonFixture fixture) {
|
||||
return fixture.read();
|
||||
}
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports",
|
||||
"java.base/jdk.internal.event=ALL-UNNAMED",
|
||||
"-XX:StartFlightRecording:jdk.SocketRead#enabled=true,jdk.SocketRead#threshold=1s,jdk.SocketRead#throttle=off"})
|
||||
@Benchmark
|
||||
public int socketReadJFREnabledEventNotEmitted(SkeletonFixture fixture) {
|
||||
return fixture.read();
|
||||
}
|
||||
|
||||
@Fork(value = 1, jvmArgs = {
|
||||
"--add-exports","java.base/jdk.internal.event=ALL-UNNAMED",
|
||||
"-XX:StartFlightRecording:jdk.SocketRead#enabled=true,jdk.SocketRead#threshold=0ms,disk=false,jdk.SocketRead#stackTrace=false,jdk.SocketRead#throttle=off"})
|
||||
@Benchmark
|
||||
public int socketReadJFREnabledEventEmitted(SkeletonFixture fixture) {
|
||||
return fixture.read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixture with fake read/write operations that have only the JFR event
|
||||
* boilerplate code for managing jfr events. No actual transfer is done
|
||||
* to eliminate the I/O portion and measure the overhead of JFR event
|
||||
* handling in it's various states.
|
||||
*/
|
||||
@State(Scope.Thread)
|
||||
public static class SkeletonFixture {
|
||||
|
||||
private final InetSocketAddress remote = new InetSocketAddress("localhost",5000);
|
||||
|
||||
public SocketAddress getRemoteAddress() {
|
||||
return remote;
|
||||
}
|
||||
|
||||
public int write() {
|
||||
if (! SocketWriteEvent.enabled()) {
|
||||
return write0();
|
||||
}
|
||||
int nbytes = 0;
|
||||
long start = SocketWriteEvent.timestamp();
|
||||
try {
|
||||
nbytes = write0();
|
||||
} finally {
|
||||
SocketWriteEvent.offer(start, nbytes, getRemoteAddress());
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
private int write0() {
|
||||
return 1024;
|
||||
}
|
||||
|
||||
public int read() {
|
||||
if (! SocketReadEvent.enabled()) {
|
||||
return read0();
|
||||
}
|
||||
int nbytes = 0;
|
||||
long start = SocketReadEvent.timestamp();
|
||||
try {
|
||||
nbytes = read0();
|
||||
} finally {
|
||||
SocketReadEvent.offer(start, nbytes, getRemoteAddress(), 0);
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
private int read0() {
|
||||
return 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
221
test/micro/org/openjdk/bench/java/net/SocketReadWrite.java
Normal file
221
test/micro/org/openjdk/bench/java/net/SocketReadWrite.java
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Benchmark socket read/write.
|
||||
*
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 10, time = 1)
|
||||
@Measurement(iterations = 5, time = 2)
|
||||
@Fork(value = 3)
|
||||
public class SocketReadWrite {
|
||||
|
||||
@Param({"1", "8192", "128000"})
|
||||
public int size;
|
||||
|
||||
@Param({"false", "true"})
|
||||
public boolean timeout;
|
||||
|
||||
static final InetAddress address = InetAddress.getLoopbackAddress();
|
||||
public static final int TIMEOUT = 10000;
|
||||
|
||||
static class EchoServer implements Runnable {
|
||||
// EchoServer is implemented to execute the same amount echo threads as benchmarking threads are running
|
||||
|
||||
final ServerSocket ss;
|
||||
final int port;
|
||||
final CountDownLatch startedLatch;
|
||||
final int size;
|
||||
final boolean timeout;
|
||||
List<ServerThread> threads = new ArrayList<>();
|
||||
volatile boolean isDone = false;
|
||||
|
||||
public EchoServer(CountDownLatch await, int size, boolean timeout) throws IOException {
|
||||
this.size = size;
|
||||
this.timeout = timeout;
|
||||
ss = new ServerSocket(0);
|
||||
port = ss.getLocalPort();
|
||||
this.startedLatch = await;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
startedLatch.countDown();
|
||||
while (!isDone) {
|
||||
try {
|
||||
Socket s = ss.accept();
|
||||
s.setTcpNoDelay(true);
|
||||
if (timeout) {
|
||||
s.setSoTimeout(TIMEOUT);
|
||||
}
|
||||
ServerThread st = new ServerThread(s, size);
|
||||
threads.add(st);
|
||||
new Thread(st).start();
|
||||
} catch (IOException e) {
|
||||
if (!isDone) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void close() throws IOException {
|
||||
if (!isDone) {
|
||||
isDone = true;
|
||||
ss.close();
|
||||
for (ServerThread st : threads) {
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static EchoServer instance = null;
|
||||
|
||||
static synchronized EchoServer startServer(int size, boolean timeout) throws IOException {
|
||||
if (instance == null) {
|
||||
CountDownLatch started = new CountDownLatch(1);
|
||||
EchoServer s = new EchoServer(started, size, timeout);
|
||||
new Thread(s).start();
|
||||
try {
|
||||
started.await(); // wait until server thread started
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
instance = s;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static class ServerThread implements Runnable {
|
||||
|
||||
final Socket s;
|
||||
final InputStream in;
|
||||
final OutputStream out;
|
||||
final int size;
|
||||
volatile boolean isDone = false;
|
||||
|
||||
ServerThread(Socket s, int size) throws IOException {
|
||||
this.s = s;
|
||||
this.size = size;
|
||||
in = s.getInputStream();
|
||||
out = s.getOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
byte[] a = new byte[size];
|
||||
while (!isDone) {
|
||||
try {
|
||||
readN(a, size, this.in);
|
||||
out.write(a);
|
||||
} catch (IOException e) {
|
||||
if (!isDone) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
isDone = true;
|
||||
s.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void readN(byte[] array, int size, InputStream in) throws IOException {
|
||||
int nread = 0;
|
||||
while (size > 0) {
|
||||
int n = in.read(array, nread, size);
|
||||
if (n < 0) throw new RuntimeException();
|
||||
nread += n;
|
||||
size -= n;
|
||||
}
|
||||
}
|
||||
|
||||
EchoServer server;
|
||||
|
||||
Socket s;
|
||||
InputStream in;
|
||||
OutputStream out;
|
||||
byte[] array;
|
||||
|
||||
@Setup
|
||||
public void setup() throws IOException {
|
||||
server = EchoServer.startServer(size, timeout);
|
||||
int port = server.port;
|
||||
s = new Socket(address, port);
|
||||
s.setTcpNoDelay(true);
|
||||
if (timeout) {
|
||||
s.setSoTimeout(TIMEOUT);
|
||||
// 10 seconds times is quite large and never will happen (for microbenchmarking),
|
||||
// but it's required since other paths inside SocketImpl are involved
|
||||
}
|
||||
in = s.getInputStream();
|
||||
out = s.getOutputStream();
|
||||
array = new byte[size];
|
||||
ThreadLocalRandom.current().nextBytes(array);
|
||||
}
|
||||
|
||||
@TearDown
|
||||
public void tearDown() throws IOException {
|
||||
server.close();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void echo() throws IOException {
|
||||
out.write(array);
|
||||
readN(array, size, in);
|
||||
}
|
||||
}
|
||||
259
test/micro/org/openjdk/bench/java/net/SocketStreaming.java
Normal file
259
test/micro/org/openjdk/bench/java/net/SocketStreaming.java
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Micro benchmark for streaming data over a Socket.
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 3)
|
||||
public class SocketStreaming {
|
||||
|
||||
/** The bytes to write/read. */
|
||||
public static final int dataLength = 16383;
|
||||
/** setTcpNoDelay(noNagle) */
|
||||
public static final boolean noNagle = false;
|
||||
|
||||
private WriterThread writerThread;
|
||||
private Socket readSocket;
|
||||
private byte[] bytes;
|
||||
|
||||
@Setup
|
||||
public void prepare() throws Exception {
|
||||
bytes = new byte[dataLength];
|
||||
|
||||
// Setup the writer thread
|
||||
writerThread = new WriterThread(dataLength, noNagle);
|
||||
writerThread.start();
|
||||
|
||||
// Wait for a read socket
|
||||
readSocket = writerThread.waitForReadSocket();
|
||||
}
|
||||
|
||||
@TearDown
|
||||
public void cleanup() throws IOException {
|
||||
// Take down the writer thread and the reader socket
|
||||
writerThread.finish();
|
||||
while (!readSocket.isClosed()) {
|
||||
readSocket.close();
|
||||
}
|
||||
readSocket = null;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testSocketInputStreamRead() throws InterruptedException, IOException {
|
||||
InputStream in = readSocket.getInputStream();
|
||||
|
||||
// Notify the writer thread to add elements to stream
|
||||
writerThread.requestSendBytes();
|
||||
|
||||
// Read these from the stream
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < dataLength) {
|
||||
int lastRead = in.read(bytes);
|
||||
if (lastRead < 0) {
|
||||
throw new InternalError("Unexpectedly got " + lastRead + " bytes from the socket");
|
||||
}
|
||||
bytesRead += lastRead;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread used to write bytes to a socket.
|
||||
*/
|
||||
private class WriterThread extends Thread {
|
||||
|
||||
/** The number of bytes to write. */
|
||||
private int dataLength;
|
||||
/** setTcpNoDelay(noNagle) */
|
||||
private boolean noNagle;
|
||||
/** Lock needed to send sendBytes requests. */
|
||||
private final Object sendBytesLock = new Object();
|
||||
/** Indicates that a sendBytes has been requested. */
|
||||
private boolean sendBytesRequested;
|
||||
/** Indicates that no more sendBytes will be requested. Time to shutdown. */
|
||||
private boolean sendBytesDone;
|
||||
/** Lock needed to protect the connectPort variable. */
|
||||
private final Object connectLock = new Object();
|
||||
/** The port the read socket should connect to. */
|
||||
private int connectPort = -1;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dataLength The number of bytes to write
|
||||
* @param noNagle setTcpNoDelay(noNagle)
|
||||
*/
|
||||
public WriterThread(int dataLength, boolean noNagle) {
|
||||
super("Load producer");
|
||||
this.dataLength = dataLength;
|
||||
this.noNagle = noNagle;
|
||||
}
|
||||
|
||||
/** Entry point for data sending helper thread. */
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Socket writeSocket;
|
||||
ServerSocket serverSocket = new ServerSocket(0);
|
||||
|
||||
/* Tell the other thread that we now know the port number.
|
||||
* The other thread will now start to connect until the following accept() call succeeds.
|
||||
*/
|
||||
synchronized (connectLock) {
|
||||
connectPort = serverSocket.getLocalPort();
|
||||
connectLock.notify();
|
||||
}
|
||||
|
||||
// Wait for the other thread to connect
|
||||
writeSocket = serverSocket.accept();
|
||||
writeSocket.setTcpNoDelay(noNagle);
|
||||
|
||||
// No more connects so this can be closed
|
||||
serverSocket.close();
|
||||
serverSocket = null;
|
||||
|
||||
OutputStream out = writeSocket.getOutputStream();
|
||||
|
||||
// Iterate as long as sendBytes are issued
|
||||
while (waitForSendBytesRequest()) {
|
||||
sendBytes(out);
|
||||
}
|
||||
|
||||
// Time to shutdown
|
||||
while (!writeSocket.isClosed()) {
|
||||
writeSocket.close();
|
||||
}
|
||||
writeSocket = null;
|
||||
} catch (Exception e) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends bytes to the output stream
|
||||
*
|
||||
* @param out The output stream
|
||||
* @throws IOException
|
||||
*/
|
||||
private void sendBytes(OutputStream out) throws IOException {
|
||||
byte outBytes[] = new byte[dataLength];
|
||||
|
||||
int bytesToSend = dataLength;
|
||||
int bytesSent = 0;
|
||||
while (bytesSent < bytesToSend) {
|
||||
out.write(outBytes);
|
||||
bytesSent += outBytes.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the readSocket and returns it when it is ready.
|
||||
*
|
||||
* @return The socket to read from
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@SuppressWarnings("SleepWhileHoldingLock")
|
||||
public Socket waitForReadSocket() throws InterruptedException {
|
||||
int theConnectPort = waitForConnectPort();
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
return new Socket(InetAddress.getByName(null), theConnectPort);
|
||||
} catch (IOException e) {
|
||||
// Wait some more for the server thread to get going
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for next sendBytes request
|
||||
*
|
||||
* @return <code>true</code> if it is time to sendBytes, <code>false</code> if it is time to shutdown
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public boolean waitForSendBytesRequest() throws InterruptedException {
|
||||
synchronized (sendBytesLock) {
|
||||
while (!sendBytesRequested && !sendBytesDone) {
|
||||
sendBytesLock.wait();
|
||||
}
|
||||
|
||||
// Clear the flag
|
||||
sendBytesRequested = false;
|
||||
|
||||
return !sendBytesDone;
|
||||
}
|
||||
}
|
||||
|
||||
/** Requests a sendBytes. */
|
||||
public void requestSendBytes() {
|
||||
synchronized (sendBytesLock) {
|
||||
sendBytesRequested = true;
|
||||
sendBytesLock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
/** Tells the writerThread that it is time to shutdown. */
|
||||
public void finish() {
|
||||
synchronized (sendBytesLock) {
|
||||
sendBytesDone = true;
|
||||
sendBytesLock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
private int waitForConnectPort() throws InterruptedException {
|
||||
synchronized (connectLock) {
|
||||
while (connectPort == -1) {
|
||||
connectLock.wait();
|
||||
}
|
||||
return connectPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2024, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.CompilerControl;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.lang.invoke.MethodType.methodType;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 1, jvmArgs = "--add-exports=java.base/sun.net.www=ALL-UNNAMED")
|
||||
public class ThreadLocalParseUtil {
|
||||
|
||||
private static final MethodHandle MH_DECODE;
|
||||
private static final MethodHandle MH_TO_URI;
|
||||
|
||||
static {
|
||||
final MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
try {
|
||||
Class<?> c = Class.forName("sun.net.www.ParseUtil");
|
||||
MH_DECODE = lookup.findStatic(c, "decode", methodType(String.class, String.class));
|
||||
MH_TO_URI = lookup.findStatic(c, "toURI", methodType(URI.class, URL.class));
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public String decodeTest() throws Throwable {
|
||||
return (String) MH_DECODE.invokeExact("/xyz/\u00A0\u00A0");
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public URI appendEncodedTest() throws Throwable {
|
||||
@SuppressWarnings("deprecation")
|
||||
URL url = new URL("https://example.com/xyz/abc/def?query=#30");
|
||||
return (URI) MH_TO_URI.invokeExact(url);
|
||||
}
|
||||
}
|
||||
67
test/micro/org/openjdk/bench/java/net/ThreadLocalURI.java
Normal file
67
test/micro/org/openjdk/bench/java/net/ThreadLocalURI.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.CompilerControl;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 3)
|
||||
public class ThreadLocalURI {
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public URI uriEncoderTest() throws URISyntaxException {
|
||||
return new URI("http", "\u00A0", "\u00A0");
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public URI uriDecoderBaseline() throws URISyntaxException {
|
||||
return new URI("https", "example.com", "/xyz/abc/def?query=", "#30");
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public String uriDecoderTest() throws URISyntaxException {
|
||||
return new URI("https", "example.com", "/xyz/abc/def?query=", "#30")
|
||||
.getPath();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright Amazon.com Inc. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests Java.net.URI.create performance on various URI types.
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 3)
|
||||
public class URIAuthorityParsingBenchmark {
|
||||
|
||||
@Param({
|
||||
"https://98765432101.abc.xyz.com",
|
||||
"https://ABCDEFGHIJK.abc.xyz.com"
|
||||
})
|
||||
private String uri;
|
||||
|
||||
@Benchmark
|
||||
public void create(Blackhole blackhole) {
|
||||
blackhole.consume(URI.create(uri));
|
||||
}
|
||||
|
||||
}
|
||||
207
test/micro/org/openjdk/bench/java/net/URLEncodeDecode.java
Normal file
207
test/micro/org/openjdk/bench/java/net/URLEncodeDecode.java
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests java.net.URLEncoder.encode and Decoder.decode.
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 3)
|
||||
public class URLEncodeDecode {
|
||||
|
||||
private static final int COUNT = 1024;
|
||||
|
||||
@Param("1024")
|
||||
public int maxLength;
|
||||
|
||||
/**
|
||||
* Percentage of strings that will remain unchanged by an encoding/decoding (0-100)
|
||||
*/
|
||||
@Param({"0", "75", "100"})
|
||||
public int unchanged;
|
||||
|
||||
/**
|
||||
* Percentage of chars in changed strings that cause encoding/decoding to happen (0-100)
|
||||
*/
|
||||
@Param({"6"})
|
||||
public int encodeChars;
|
||||
|
||||
public String[] testStringsEncode;
|
||||
public String[] testStringsDecode;
|
||||
public String[] toStrings;
|
||||
|
||||
@Setup()
|
||||
public void setupStrings() {
|
||||
char[] encodeTokens = new char[] { '[', '(', ' ', '\u00E4', '\u00E5', '\u00F6', ')', '='};
|
||||
char[] tokens = new char[('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1) + 4];
|
||||
int n = 0;
|
||||
for (char c = '0'; c <= '9'; c++) {
|
||||
tokens[n++] = c;
|
||||
}
|
||||
for (char c = 'A'; c <= 'Z'; c++) {
|
||||
tokens[n++] = c;
|
||||
}
|
||||
for (char c = 'a'; c <= 'z'; c++) {
|
||||
tokens[n++] = c;
|
||||
}
|
||||
tokens[n++] = '-';
|
||||
tokens[n++] = '_';
|
||||
tokens[n++] = '.';
|
||||
tokens[n] = '*';
|
||||
|
||||
Random r = new Random(3);
|
||||
testStringsEncode = new String[COUNT];
|
||||
testStringsDecode = new String[COUNT];
|
||||
toStrings = new String[COUNT];
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
int l = r.nextInt(maxLength);
|
||||
boolean needEncoding = r.nextInt(100) >= unchanged;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean hasEncoded = false;
|
||||
for (int j = 0; j < l; j++) {
|
||||
if (needEncoding && r.nextInt(100) < encodeChars) {
|
||||
addToken(encodeTokens, r, sb);
|
||||
hasEncoded = true;
|
||||
} else {
|
||||
addToken(tokens, r, sb);
|
||||
}
|
||||
}
|
||||
if (needEncoding && !hasEncoded) {
|
||||
addToken(encodeTokens, r, sb);
|
||||
}
|
||||
testStringsEncode[i] = sb.toString();
|
||||
}
|
||||
int countUnchanged = 0;
|
||||
for (String s : testStringsEncode) {
|
||||
if (s.equals(java.net.URLEncoder.encode(s, StandardCharsets.UTF_8))) {
|
||||
countUnchanged++;
|
||||
} else {
|
||||
if (unchanged == 100) {
|
||||
System.out.println("Unexpectedly needs encoding action: ");
|
||||
System.out.println("\t" + s);
|
||||
System.out.println("\t" + java.net.URLEncoder.encode(s, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
System.out.println("Generated " + testStringsEncode.length + " encodable strings, " + countUnchanged + " of which does not need encoding action");
|
||||
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
int l = r.nextInt(maxLength);
|
||||
boolean needDecoding = r.nextInt(100) >= unchanged;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean hasDecoded = false;
|
||||
for (int j = 0; j < l; j++) {
|
||||
if (needDecoding && r.nextInt(100) < encodeChars) {
|
||||
addDecodableChar(tokens, r, sb);
|
||||
hasDecoded = true;
|
||||
} else {
|
||||
addToken(tokens, r, sb);
|
||||
}
|
||||
}
|
||||
if (needDecoding && !hasDecoded) {
|
||||
addDecodableChar(tokens, r, sb);
|
||||
}
|
||||
testStringsDecode[i] = sb.toString();
|
||||
}
|
||||
countUnchanged = 0;
|
||||
for (String s : testStringsDecode) {
|
||||
if (s.equals(java.net.URLDecoder.decode(s, StandardCharsets.UTF_8))) {
|
||||
countUnchanged++;
|
||||
} else {
|
||||
if (unchanged == 100) {
|
||||
System.out.println("Unexpectedly needs encoding action: ");
|
||||
System.out.println("\t" + s);
|
||||
System.out.println("\t" + java.net.URLDecoder.decode(s, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Generated " + testStringsDecode.length + " decodable strings, " + countUnchanged + " of which does not need decoding action");
|
||||
}
|
||||
|
||||
private static void addToken(char[] tokens, Random r, StringBuilder sb) {
|
||||
int c = r.nextInt(tokens.length);
|
||||
sb.append(tokens[c]);
|
||||
}
|
||||
|
||||
private static void addDecodableChar(char[] tokens, Random r, StringBuilder sb) {
|
||||
if (r.nextInt(100) < 15) {
|
||||
sb.append('+'); // exercise '+' -> ' ' decoding paths.
|
||||
} else {
|
||||
sb.append("%").append(tokens[r.nextInt(16)]).append(tokens[r.nextInt(16)]);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testEncodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
|
||||
for (String s : testStringsEncode) {
|
||||
bh.consume(java.net.URLEncoder.encode(s, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testDecodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
|
||||
for (String s : testStringsDecode) {
|
||||
bh.consume(URLDecoder.decode(s, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Benchmark
|
||||
public void testEncodeLatin1(Blackhole bh) throws UnsupportedEncodingException {
|
||||
for (String s : testStringsEncode) {
|
||||
bh.consume(java.net.URLEncoder.encode(s, StandardCharsets.ISO_8859_1));
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testDecodeLatin1(Blackhole bh) throws UnsupportedEncodingException {
|
||||
for (String s : testStringsDecode) {
|
||||
bh.consume(URLDecoder.decode(s, StandardCharsets.ISO_8859_1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
77
test/micro/org/openjdk/bench/java/net/URLToString.java
Normal file
77
test/micro/org/openjdk/bench/java/net/URLToString.java
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2026, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests java.net.URL.toString performance
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 3)
|
||||
public class URLToString {
|
||||
|
||||
@Param({"false", "true"})
|
||||
boolean auth;
|
||||
|
||||
@Param({"false", "true"})
|
||||
boolean query;
|
||||
|
||||
@Param({"false", "true"})
|
||||
boolean ref;
|
||||
|
||||
private URL url;
|
||||
|
||||
@Setup()
|
||||
public void setup() throws MalformedURLException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (auth) {
|
||||
sb.append("http://hostname");
|
||||
} else {
|
||||
sb.append("file:");
|
||||
}
|
||||
sb.append("/some/long/path/to/jar/app-1.0.jar!/org/summerframework/samples/horseclinic/HorseClinicApplication.class");
|
||||
if (query) {
|
||||
sb.append("?param=value");
|
||||
}
|
||||
if (ref) {
|
||||
sb.append("#fragment");
|
||||
}
|
||||
|
||||
url = URI.create(sb.toString()).toURL();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public String urlToString() {
|
||||
return url.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2025, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.StandardProtocolFamily;
|
||||
import java.net.UnixDomainSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.file.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
/**
|
||||
* Tests the overheads of I/O API.
|
||||
* This test is known to depend heavily on network conditions and paltform.
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 3)
|
||||
public class UnixSocketChannelReadWrite {
|
||||
|
||||
private ServerSocketChannel ssc;
|
||||
private Path sscFilePath;
|
||||
private SocketChannel s1, s2;
|
||||
private ReadThread rt;
|
||||
private ByteBuffer bb = ByteBuffer.allocate(1);
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void beforeRun() throws IOException {
|
||||
ssc = ServerSocketChannel.open(StandardProtocolFamily.UNIX).bind(null);
|
||||
// Record the UDS file path right after binding, as the socket may be
|
||||
// closed later due to a failure, and subsequent calls to `getPath()`
|
||||
// will throw.
|
||||
sscFilePath = ((UnixDomainSocketAddress) ssc.getLocalAddress()).getPath();
|
||||
s1 = SocketChannel.open(ssc.getLocalAddress());
|
||||
s2 = ssc.accept();
|
||||
|
||||
rt = new ReadThread(s2);
|
||||
rt.start();
|
||||
|
||||
bb.put((byte) 47);
|
||||
bb.flip();
|
||||
}
|
||||
|
||||
@TearDown(Level.Trial)
|
||||
public void afterRun() throws IOException, InterruptedException {
|
||||
s1.close();
|
||||
s2.close();
|
||||
ssc.close();
|
||||
Files.delete(sscFilePath);
|
||||
rt.join();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void test() throws IOException {
|
||||
s1.write(bb);
|
||||
bb.flip();
|
||||
}
|
||||
|
||||
static class ReadThread extends Thread {
|
||||
private SocketChannel sc;
|
||||
|
||||
public ReadThread(SocketChannel s2) {
|
||||
this.sc = s2;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
ByteBuffer bb = ByteBuffer.allocate(1);
|
||||
while (sc.read(bb) > 0) {
|
||||
bb.flip();
|
||||
}
|
||||
} catch (ClosedChannelException ex) {
|
||||
// shutdown time
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue