Reduce number of String allocation in Stratum worker

Currently we allocate a string in the heap per each worker check (not even
read) and clone message in write. This pr introduces a buffer which is
used for a round of workers check and remove clone in write_message.
Read optimization reduces number of allocations by factor of N (where N
is a number of workers), if N = 1 number of allocations doesn't change.
This commit is contained in:
hashmap 2019-01-18 15:11:13 +01:00
parent bb933dcd69
commit a3f68d8d1f
No known key found for this signature in database
GPG key ID: 5EA3C2D2455ED9C8

View file

@ -168,12 +168,11 @@ impl Worker {
} }
// Get Message from the worker // Get Message from the worker
fn read_message(&mut self) -> Option<String> { fn read_message(&mut self, line: &mut String) -> Option<usize> {
// Read and return a single message or None // Read and return a single message or None
let mut line = String::new(); match self.stream.read_line(line) {
match self.stream.read_line(&mut line) { Ok(n) => {
Ok(_) => { return Some(n);
return Some(line);
} }
Err(ref e) if e.kind() == ErrorKind::WouldBlock => { Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
// Not an error, just no messages ready // Not an error, just no messages ready
@ -191,9 +190,8 @@ impl Worker {
} }
// Send Message to the worker // Send Message to the worker
fn write_message(&mut self, message_in: String) { fn write_message(&mut self, mut message: String) {
// Write and Flush the message // Write and Flush the message
let mut message = message_in.clone();
if !message.ends_with("\n") { if !message.ends_with("\n") {
message += "\n"; message += "\n";
} }
@ -283,9 +281,10 @@ impl StratumServer {
// Handle an RPC request message from the worker(s) // Handle an RPC request message from the worker(s)
fn handle_rpc_requests(&mut self, stratum_stats: &mut Arc<RwLock<StratumStats>>) { fn handle_rpc_requests(&mut self, stratum_stats: &mut Arc<RwLock<StratumStats>>) {
let mut workers_l = self.workers.lock(); let mut workers_l = self.workers.lock();
let mut the_message = String::with_capacity(4096);
for num in 0..workers_l.len() { for num in 0..workers_l.len() {
match workers_l[num].read_message() { match workers_l[num].read_message(&mut the_message) {
Some(the_message) => { Some(_) => {
// Decompose the request from the JSONRpc wrapper // Decompose the request from the JSONRpc wrapper
let request: RpcRequest = match serde_json::from_str(&the_message) { let request: RpcRequest = match serde_json::from_str(&the_message) {
Ok(request) => request, Ok(request) => request,