scenario 1.
in this scenario i used message passing and a calculate operation
first spawn some worker ( number == my cpu core)
then sending request to each worker and await for result of each worker and it do simple sum over N counter and then response Result::Ok in rust
Rust+Tokio: 61,942 ~ 79,300 (microseconds)
Elixir/Beam: 23,393 microseconds
after set Rust compiler opt-level = 3
Rust + Tokio improved performance
from: 144,792 ns
to: 60,000 ~ 70,000 ns
Rust Server
pub mod server {
use tokio::sync::mpsc::{self};
use tokio::sync::oneshot::{self};
pub struct Request<MReq, MResp> {
pub msg : MReq,
pub resp: oneshot::Sender<MResp>
}
pub enum MReq {
Event(i32)
}
pub enum MResp {
Event(Result<(), ()>)
}
pub async fn start() -> mpsc::Sender<Request<MReq, MResp>> {
let (client, mut server) =
mpsc::channel::<Request<MReq, MResp>>(16);
tokio::spawn(async move {
while let Some(req) = server.recv().await {
let MReq::Event(n) = req.msg;
{
let mut temp = 1;
for num in 1..n {
temp += num;
}
}
let _ = req.resp.send(MResp::Event(Ok(())));
}
});
client
}
}
Rust Client
use chrono::PreciseTime;
mod server;
use server::server::{ start, MReq, MResp, Request};
use tokio::{sync::oneshot::{self, Receiver}};
#[tokio::main]
async fn main() {
let server1 = start().await;
let server2 = start().await;
let server3 = start().await;
let start = PreciseTime::now();
// ===================================================
for n in 0..1000 {
let (recv_resp1, req1) = request_factory(n);
let (recv_resp2, req2) = request_factory(n);
let (recv_resp3, req3) = request_factory(n);
let _ = server1.send(req1).await;
let _ = recv_resp1.await;
let _ = server2.send(req2).await;
let _ = recv_resp2.await;
let _ = server3.send(req3).await;
let _ = recv_resp3.await;
}
// ===================================================
let end = PreciseTime::now();
let tm = start.to(end).num_microseconds().unwrap();
println!("==> {} ns (microseconds)", tm)
}
fn request_factory(n: i32) -> (Receiver<MResp>, Request<MReq, MResp>) {
let (resp, recv) = oneshot::channel::<MResp>();
let req = Request::<MReq, MResp> {
msg: MReq::Event(n),
resp
};
(recv, req)
}
my Elixir code is normal code, i dont use any tricks for increasing
performance just use GenServer