mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
bench: remove http benchmarks (#26484)
These benchmarks run on GitHub Actions and are extremely noisy, thus not providing much value.
This commit is contained in:
parent
09e36d41b0
commit
fd8bf08271
10 changed files with 2 additions and 291 deletions
|
@ -1,167 +0,0 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::net::TcpStream;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::sync::atomic::AtomicU16;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
use super::Result;
|
||||
|
||||
pub use test_util::parse_wrk_output;
|
||||
pub use test_util::WrkOutput as HttpBenchmarkResult;
|
||||
// Some of the benchmarks in this file have been renamed. In case the history
|
||||
// somehow gets messed up:
|
||||
// "node_http" was once called "node"
|
||||
// "deno_tcp" was once called "deno"
|
||||
// "deno_http" was once called "deno_net_http"
|
||||
|
||||
const DURATION: &str = "10s";
|
||||
|
||||
pub fn benchmark(
|
||||
target_path: &Path,
|
||||
) -> Result<HashMap<String, HttpBenchmarkResult>> {
|
||||
let deno_exe = test_util::deno_exe_path();
|
||||
let deno_exe = deno_exe.to_string();
|
||||
|
||||
let hyper_hello_exe = target_path.join("test_server");
|
||||
let hyper_hello_exe = hyper_hello_exe.to_str().unwrap();
|
||||
|
||||
let mut res = HashMap::new();
|
||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
let http_dir = manifest_dir.join("bench").join("http");
|
||||
for entry in std::fs::read_dir(&http_dir)? {
|
||||
let entry = entry?;
|
||||
let pathbuf = entry.path();
|
||||
let path = pathbuf.to_str().unwrap();
|
||||
if path.ends_with(".lua") {
|
||||
continue;
|
||||
}
|
||||
let file_stem = pathbuf.file_stem().unwrap().to_str().unwrap();
|
||||
|
||||
let lua_script = http_dir.join(format!("{file_stem}.lua"));
|
||||
let mut maybe_lua = None;
|
||||
if lua_script.exists() {
|
||||
maybe_lua = Some(lua_script.to_str().unwrap());
|
||||
}
|
||||
|
||||
let port = get_port();
|
||||
// deno run -A --unstable-net <path> <addr>
|
||||
res.insert(
|
||||
file_stem.to_string(),
|
||||
run(
|
||||
&[
|
||||
deno_exe.as_str(),
|
||||
"run",
|
||||
"--allow-all",
|
||||
"--unstable-net",
|
||||
"--enable-testing-features-do-not-use",
|
||||
path,
|
||||
&server_addr(port),
|
||||
],
|
||||
port,
|
||||
None,
|
||||
None,
|
||||
maybe_lua,
|
||||
)?,
|
||||
);
|
||||
}
|
||||
|
||||
res.insert("hyper".to_string(), hyper_http(hyper_hello_exe)?);
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn run(
|
||||
server_cmd: &[&str],
|
||||
port: u16,
|
||||
env: Option<Vec<(String, String)>>,
|
||||
origin_cmd: Option<&[&str]>,
|
||||
lua_script: Option<&str>,
|
||||
) -> Result<HttpBenchmarkResult> {
|
||||
// Wait for port 4544 to become available.
|
||||
// TODO Need to use SO_REUSEPORT with tokio::net::TcpListener.
|
||||
std::thread::sleep(Duration::from_secs(5));
|
||||
|
||||
let mut origin = None;
|
||||
if let Some(cmd) = origin_cmd {
|
||||
let mut com = Command::new(cmd[0]);
|
||||
com.args(&cmd[1..]);
|
||||
if let Some(env) = env.clone() {
|
||||
com.envs(env);
|
||||
}
|
||||
origin = Some(com.spawn()?);
|
||||
};
|
||||
|
||||
println!("{}", server_cmd.join(" "));
|
||||
let mut server = {
|
||||
let mut com = Command::new(server_cmd[0]);
|
||||
com.args(&server_cmd[1..]);
|
||||
if let Some(env) = env {
|
||||
com.envs(env);
|
||||
}
|
||||
com.spawn()?
|
||||
};
|
||||
|
||||
// Wait for server to wake up.
|
||||
let now = Instant::now();
|
||||
let addr = format!("127.0.0.1:{port}");
|
||||
while now.elapsed().as_secs() < 30 {
|
||||
if TcpStream::connect(&addr).is_ok() {
|
||||
break;
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
TcpStream::connect(&addr).expect("Failed to connect to server in time");
|
||||
println!("Server took {} ms to start", now.elapsed().as_millis());
|
||||
|
||||
let wrk = test_util::prebuilt_tool_path("wrk");
|
||||
assert!(wrk.is_file());
|
||||
|
||||
let addr = format!("http://{addr}/");
|
||||
let wrk = wrk.to_string();
|
||||
let mut wrk_cmd = vec![wrk.as_str(), "-d", DURATION, "--latency", &addr];
|
||||
|
||||
if let Some(lua_script) = lua_script {
|
||||
wrk_cmd.push("-s");
|
||||
wrk_cmd.push(lua_script);
|
||||
}
|
||||
|
||||
println!("{}", wrk_cmd.join(" "));
|
||||
let output = test_util::run_collect(&wrk_cmd, None, None, None, true).0;
|
||||
|
||||
std::thread::sleep(Duration::from_secs(1)); // wait to capture failure. TODO racy.
|
||||
|
||||
println!("{output}");
|
||||
assert!(
|
||||
server.try_wait()?.map(|s| s.success()).unwrap_or(true),
|
||||
"server ended with error"
|
||||
);
|
||||
|
||||
server.kill()?;
|
||||
if let Some(mut origin) = origin {
|
||||
origin.kill()?;
|
||||
}
|
||||
|
||||
Ok(parse_wrk_output(&output))
|
||||
}
|
||||
|
||||
static NEXT_PORT: AtomicU16 = AtomicU16::new(4544);
|
||||
pub(crate) fn get_port() -> u16 {
|
||||
let p = NEXT_PORT.load(Ordering::SeqCst);
|
||||
NEXT_PORT.store(p.wrapping_add(1), Ordering::SeqCst);
|
||||
p
|
||||
}
|
||||
|
||||
fn server_addr(port: u16) -> String {
|
||||
format!("0.0.0.0:{port}")
|
||||
}
|
||||
|
||||
fn hyper_http(exe: &str) -> Result<HttpBenchmarkResult> {
|
||||
let port = get_port();
|
||||
println!("http_benchmark testing RUST hyper");
|
||||
run(&[exe, &port.to_string()], port, None, None, None)
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
import { Hono } from "https://deno.land/x/hono@v2.0.9/mod.ts";
|
||||
|
||||
const addr = Deno.args[0] || "127.0.0.1:4500";
|
||||
const [hostname, port] = addr.split(":");
|
||||
|
||||
const app = new Hono();
|
||||
app.get("/", (c) => c.text("Hello, World!"));
|
||||
|
||||
Deno.serve({ port: Number(port), hostname }, app.fetch);
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
const addr = Deno.args[0] || "127.0.0.1:4500";
|
||||
const [hostname, port] = addr.split(":");
|
||||
const { serve } = Deno;
|
||||
|
||||
const path = new URL("../testdata/128k.bin", import.meta.url).pathname;
|
||||
|
||||
function handler() {
|
||||
const file = Deno.openSync(path);
|
||||
return new Response(file.readable);
|
||||
}
|
||||
|
||||
serve({ hostname, port: Number(port) }, handler);
|
|
@ -1,5 +0,0 @@
|
|||
wrk.headers["foo"] = "bar"
|
||||
wrk.headers["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
|
||||
wrk.headers["Viewport-Width"] = "1920"
|
||||
wrk.headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
wrk.headers["Accept-Language"] = "en,la;q=0.9"
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
const addr = Deno.args[0] ?? "127.0.0.1:4500";
|
||||
const [hostname, port] = addr.split(":");
|
||||
const { serve } = Deno;
|
||||
|
||||
function handler() {
|
||||
return new Response("Hello World");
|
||||
}
|
||||
|
||||
serve({ hostname, port: Number(port), reusePort: true }, handler);
|
|
@ -1,5 +0,0 @@
|
|||
wrk.method = "POST"
|
||||
wrk.headers["Content-Type"] = "application/octet-stream"
|
||||
|
||||
file = io.open("./cli/bench/testdata/128k.bin", "rb")
|
||||
wrk.body = file:read("*a")
|
|
@ -1,3 +0,0 @@
|
|||
wrk.method = "POST"
|
||||
wrk.headers["Content-Type"] = "application/json"
|
||||
wrk.body = '{"hello":"deno"}'
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { renderToReadableStream } from "https://esm.run/react-dom/server";
|
||||
import * as React from "https://esm.run/react";
|
||||
const { serve } = Deno;
|
||||
const addr = Deno.args[0] || "127.0.0.1:4500";
|
||||
const [hostname, port] = addr.split(":");
|
||||
|
||||
const App = () => (
|
||||
<html>
|
||||
<body>
|
||||
<h1>Hello World</h1>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
const headers = {
|
||||
headers: {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
};
|
||||
|
||||
serve({ hostname, port: Number(port) }, async () => {
|
||||
return new Response(await renderToReadableStream(<App />), headers);
|
||||
});
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Used for benchmarking Deno's networking.
|
||||
// TODO(bartlomieju): Replace this with a real HTTP server once
|
||||
// https://github.com/denoland/deno/issues/726 is completed.
|
||||
// Note: this is a keep-alive server.
|
||||
// deno-lint-ignore-file no-console
|
||||
const addr = Deno.args[0] || "127.0.0.1:4500";
|
||||
const [hostname, port] = addr.split(":");
|
||||
const listener = Deno.listen({ hostname, port: Number(port) });
|
||||
const response = new TextEncoder().encode(
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World\n",
|
||||
);
|
||||
async function handle(conn: Deno.Conn): Promise<void> {
|
||||
const buffer = new Uint8Array(1024);
|
||||
try {
|
||||
while (true) {
|
||||
await conn.read(buffer);
|
||||
await conn.write(response);
|
||||
}
|
||||
} catch (e) {
|
||||
if (
|
||||
!(e instanceof Deno.errors.BrokenPipe) &&
|
||||
!(e instanceof Deno.errors.ConnectionReset)
|
||||
) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
conn.close();
|
||||
}
|
||||
|
||||
console.log("Listening on", addr);
|
||||
for await (const conn of listener) {
|
||||
handle(conn);
|
||||
}
|
|
@ -17,7 +17,6 @@ use std::process::Stdio;
|
|||
use std::time::SystemTime;
|
||||
use test_util::PathRef;
|
||||
|
||||
mod http;
|
||||
mod lsp;
|
||||
|
||||
fn read_json(filename: &Path) -> Result<Value> {
|
||||
|
@ -345,9 +344,11 @@ struct BenchResult {
|
|||
binary_size: HashMap<String, i64>,
|
||||
bundle_size: HashMap<String, i64>,
|
||||
cargo_deps: usize,
|
||||
// TODO(bartlomieju): remove
|
||||
max_latency: HashMap<String, f64>,
|
||||
max_memory: HashMap<String, i64>,
|
||||
lsp_exec_time: HashMap<String, i64>,
|
||||
// TODO(bartlomieju): remove
|
||||
req_per_sec: HashMap<String, i64>,
|
||||
syscall_count: HashMap<String, i64>,
|
||||
thread_count: HashMap<String, i64>,
|
||||
|
@ -362,7 +363,6 @@ async fn main() -> Result<()> {
|
|||
"binary_size",
|
||||
"cargo_deps",
|
||||
"lsp",
|
||||
"http",
|
||||
"strace",
|
||||
"mem_usage",
|
||||
];
|
||||
|
@ -427,21 +427,6 @@ async fn main() -> Result<()> {
|
|||
new_data.lsp_exec_time = lsp_exec_times;
|
||||
}
|
||||
|
||||
if benchmarks.contains(&"http") && cfg!(not(target_os = "windows")) {
|
||||
let stats = http::benchmark(target_dir.as_path())?;
|
||||
let req_per_sec = stats
|
||||
.iter()
|
||||
.map(|(name, result)| (name.clone(), result.requests as i64))
|
||||
.collect();
|
||||
new_data.req_per_sec = req_per_sec;
|
||||
let max_latency = stats
|
||||
.iter()
|
||||
.map(|(name, result)| (name.clone(), result.latency))
|
||||
.collect();
|
||||
|
||||
new_data.max_latency = max_latency;
|
||||
}
|
||||
|
||||
if cfg!(target_os = "linux") && benchmarks.contains(&"strace") {
|
||||
use std::io::Read;
|
||||
|
||||
|
|
Loading…
Reference in a new issue