Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
200 views
in Technique[技术] by (71.8m points)

Most efficient way to read and process UDP datagrams in Rust

I have a very simple application that receives key/value objects via UDP. Each UDP packet contains a 16-byte key and the rest is the value. A tokio::net::UdpSocket is bound and used in the following loop:

let mut udp_socket = UdpSocket::bind(addr).await?;

loop {
    let mut data = Vec::with_capacity(MAX_DATAGRAM_SIZE);
    let (len, _remote_addr) = udp_socket.recv_from(&mut data).await?;

    if len >= 16 {
        let key = (&data[..16]).to_vec();
        let value = (&data[16..len]).to_vec();;
        self.core.put_object(key, value);
    }
}

This works, but is rather inefficient, because both the key and value are copied by the to_vec() function. The following approach is already a little bit more efficient, because it won't copy the key:

let value = (&data[16..len]).to_vec();
let mut key = data;
key.truncate(16);

This approach has some disadvantages:

  1. The key vector still retains MAX_DATAGRAM_SIZE bytes (don't think using shrink_to_fit will help much).
  2. The majority of the data (value bytes) is still copied.

Another option could be to use the same structure, but with the value. This would only result in copying 16 bytes and there would be less space lost, because the value is often larger than the key. I don't think this is possible, because the vector consists of a pointer, capacity and length. So you can't slice a vector in-place, because it's missing an offset.

The proper solution would be to use vectored I/O, but UdpSocket::recv_from doesn't support this.

When the key is removed, then the value is removed as well so both objects have the same lifetime. I was thinking of creating a new structure that owns the vector and can return slices to the key and value and work with that. But this would mean an overhaul of underlying code which makes it harder to read. So I am not sure if that's a decent solution. I also have two other interface (TCP and gRPC) that use the same underlying put_object method.

Any suggestions on how to deal with such an issue?

question from:https://stackoverflow.com/questions/65927782/most-efficient-way-to-read-and-process-udp-datagrams-in-rust

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...