mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Some changes in the benchmarks.
This commit is contained in:
67
benchmarks/benchmarks.md
Normal file
67
benchmarks/benchmarks.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# TCP echo server performance.
|
||||
|
||||
The main motivations for choosing an echo server to benchmark a redis
|
||||
client were
|
||||
|
||||
* Simple to implement in most languages.
|
||||
* Does not require expertise level get decent performance.
|
||||
* Excelent to measure ability to server concurrent requests.
|
||||
* It must test the ability to deal with concurrency.
|
||||
* I/O bound: In echo servers CPU consumption is very low as a result
|
||||
the performance is more related to how well concurrency is
|
||||
implemented.
|
||||
|
||||
I also imposed some constraints on the implementations
|
||||
|
||||
* Favor simple implementations that use standard idioms of their
|
||||
specific language or framework.
|
||||
* Avoid of optimization that makes it too complex e.g. connection
|
||||
pool or that requires expert level.
|
||||
|
||||
## Without Redis
|
||||
|
||||
Before we can compare the Redis clients implementation we must have a
|
||||
rough view about how different libraries compare in terms of
|
||||
performance.
|
||||
|
||||
Remarks:
|
||||
|
||||
* I was not expecting Asio to perform so much better than the alternatives that Tokio and libuv.
|
||||
* I did expect nodejs to come a little behind given it is
|
||||
implemented in javascript. Otherwise I expected it to have
|
||||
similar performance to libuv since it is the framework behind
|
||||
nodejs.
|
||||
|
||||
The code can be found at
|
||||
|
||||
* Asio: A variation of the asio example.
|
||||
* Libuv: Copy and pasted of the libuv example.
|
||||
* Tokio: Copy and pasted of the example provided here.
|
||||
* Go: Found in the internet and make adjustmenst.
|
||||
|
||||
## With Redis
|
||||
|
||||
In this case the message is not echoed directly to the client but sent
|
||||
to the server with the Ping command which will echo it back to the
|
||||
server, only after that it is sent to the client.
|
||||
|
||||
the set is.
|
||||
|
||||
The most remarkable thing here is that the Rust Redis client comes so
|
||||
far behind that it can't even be represented together with the other
|
||||
benchmarks.
|
||||
|
||||
The Reason why the Aedis and the nodejs client are so much faster than
|
||||
the alternatives is that they implement pipeline.
|
||||
|
||||
The code I used is a variation of the list given above, that I
|
||||
implemented myself. The Redis client for each language were chosen
|
||||
based on their number of stars as given here.
|
||||
|
||||
## Conclusion:
|
||||
|
||||
The main conclusion is that pipelines is fundamental, much more
|
||||
fundamental than the language performance per se.
|
||||
|
||||
If your spot any performance improvement in any of the example, please
|
||||
open a PR and I will gladly merge it.
|
||||
@@ -1,28 +1,10 @@
|
||||
\documentclass{article}
|
||||
% translate with >> pdflatex -shell-escape <file>
|
||||
|
||||
% This file is an extract of the PGFPLOTS manual, copyright by Christian Feuersaenger.
|
||||
%
|
||||
% Feel free to use it as long as you cite the pgfplots manual properly.
|
||||
%
|
||||
% See
|
||||
% http://pgfplots.sourceforge.net/pgfplots.pdf
|
||||
% for the complete manual.
|
||||
%
|
||||
% Any required input files (for <plot table> or <plot file> or the table package) can be downloaded
|
||||
% at
|
||||
% http://www.ctan.org/tex-archive/graphics/pgf/contrib/pgfplots/doc/latex/
|
||||
% and
|
||||
% http://www.ctan.org/tex-archive/graphics/pgf/contrib/pgfplots/doc/latex/plotdata/
|
||||
|
||||
|
||||
% $ time ./echo_server_client 1000 5000
|
||||
% ======================================================
|
||||
% C++: Asio
|
||||
%
|
||||
% Seq: 216.000s = 3.54 * Async.
|
||||
% Direct: 31.427s
|
||||
% Over Redis: 61.394s
|
||||
% Seq single: 2m3.934s
|
||||
% Over Redis: 5m2.083s
|
||||
% Direct: 31.427s
|
||||
%
|
||||
% ======================================================
|
||||
% C++: libuv
|
||||
@@ -50,21 +32,55 @@
|
||||
% Over Redis: 141.881s
|
||||
|
||||
|
||||
\documentclass{article}
|
||||
\usepackage{pgfplots}
|
||||
\pgfrealjobname{echo}
|
||||
\pgfplotsset{compat=newest}
|
||||
|
||||
\pagestyle{empty}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\beginpgfgraphicnamed{echo-f0}
|
||||
% time ./echo_server_client 1000 5000
|
||||
\begin{tikzpicture}
|
||||
\begin{axis}[
|
||||
y dir=reverse,
|
||||
xbar stacked,
|
||||
%xbar stacked,
|
||||
xbar, xmin=0,
|
||||
%hide x axis,
|
||||
bar shift=0pt,
|
||||
width=15cm, height=6cm, enlarge y limits=0.5,
|
||||
title={TCP echo server performance},
|
||||
xlabel={Seconds},
|
||||
symbolic y coords={Asio,Tokio,Libuv,Nodejs,Go},
|
||||
ytick=data,
|
||||
%bar width=1cm,
|
||||
nodes near coords,
|
||||
nodes near coords align={horizontal},
|
||||
]
|
||||
\addplot coordinates {
|
||||
(31.1,Asio)
|
||||
(43.2,Tokio)
|
||||
(43.6,Libuv)
|
||||
(74.2,Nodejs)
|
||||
(81.0,Go)
|
||||
};
|
||||
\end{axis}
|
||||
\end{tikzpicture}
|
||||
\endpgfgraphicnamed
|
||||
|
||||
\beginpgfgraphicnamed{echo-f1}
|
||||
%debian2[0]$ time ./echo_server_client 1000 1000
|
||||
%Go (1): 1.000s
|
||||
%C++ (1): 0.07s
|
||||
\begin{tikzpicture}
|
||||
\begin{axis}[
|
||||
y dir=reverse,
|
||||
%xbar stacked,
|
||||
xbar, xmin=0,
|
||||
%hide x axis,
|
||||
bar shift=0pt,
|
||||
width=12cm, height=6cm, enlarge y limits=0.5,
|
||||
xlabel={TCP echo server performance},
|
||||
xlabel={TCP echo server performance (over Redis)},
|
||||
symbolic y coords={Asio,Rust/Tokio,Libuv,Nodejs,Go},
|
||||
ytick=data,
|
||||
%bar width=1cm,
|
||||
@@ -72,19 +88,19 @@
|
||||
nodes near coords align={horizontal},
|
||||
]
|
||||
\addplot coordinates {
|
||||
(31.4,Asio)
|
||||
(42.2,Rust/Tokio)
|
||||
(43.6,Libuv)
|
||||
(73.0,Nodejs)
|
||||
(78.2,Go)
|
||||
};
|
||||
\addplot coordinates {
|
||||
(30.0,Asio)
|
||||
(90.6,Rust/Tokio)
|
||||
(0.0,Libuv)
|
||||
(68.9,Nodejs)
|
||||
(0.0,Go)
|
||||
(12.6,Asio)
|
||||
(28.8,Nodejs)
|
||||
(352.4,Go)
|
||||
};
|
||||
%\addplot coordinates {
|
||||
% (30.0,Asio)
|
||||
% (90.6,Rust/Tokio)
|
||||
% (0.0,Libuv)
|
||||
% (68.9,Nodejs)
|
||||
% (0.0,Go)
|
||||
%};
|
||||
\end{axis}
|
||||
\end{tikzpicture}
|
||||
\endpgfgraphicnamed
|
||||
|
||||
\end{document}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
var rdb = redis.NewClient(&redis.Options{Addr: "localhost:6379", Password: "", DB: 0,})
|
||||
var rdb = redis.NewClient(&redis.Options{Addr: "db.occase.de:6379", Password: "", DB: 0,})
|
||||
|
||||
func echo(conn net.Conn) {
|
||||
r := bufio.NewReader(conn)
|
||||
@@ -27,6 +27,7 @@ func echo(conn net.Conn) {
|
||||
|
||||
err2 := rdb.Ping(ctx).Err()
|
||||
if err2 != nil {
|
||||
fmt.Println("ERROR", err2)
|
||||
panic(err2)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createClient } from 'redis';
|
||||
import * as net from 'net';
|
||||
|
||||
const client = createClient();
|
||||
const client = createClient({url: 'redis://db.occase.de:6379' });
|
||||
client.on('error', (err) => console.log('Redis Client Error', err));
|
||||
await client.connect();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::{Arc};
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let listener = TcpListener::bind("127.0.0.1:55555").await?;
|
||||
let client = redis::Client::open("redis://127.0.0.1/").unwrap();
|
||||
let client = redis::Client::open("redis://db.occase.de/").unwrap();
|
||||
let con = Arc::new(Mutex::new(client.get_async_connection().await?));
|
||||
|
||||
loop {
|
||||
|
||||
Reference in New Issue
Block a user