问题
I am using tokio's UdpCodec trait:
pub trait UdpCodec {
type In;
type Out;
fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> Result<Self::In>;
fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> SocketAddr;
}
My associated type for In
is a (SocketAddr, Vec<Metric>)
. Metric
is defined as:
#[derive(Debug, PartialEq)]
pub struct Metric {
pub name: String,
pub value: f64,
pub metric_type: MetricType,
pub sample_rate: Option<f64>,
}
I have used owned strings to avoid lifetime constraints with the associated types. However I also do HashMap
lookups and inserts with these metric names which involves a lot of cloning since I borrow metrics in other functions.
How can I better store a string within this Metric
type to avoid many inefficient clones? Using the Cow
type has crossed my mind but it also obviously has a lifetime association.
回答1:
Expanding on @Josh's suggestion, I would suggest using interning.
Depending on how memory or CPU intensive your task is, make your pick between:
- A double hash-map:
ID
<->String
, shared between components - A single hash-map:
String
->Rc<str>
If you can afford the latter, I definitely advise it. Also note that you can likely fold MetricType
within the Rc
: Rc<(MetricType, str)>
.
Then you still need to call clone
left and right, but each is just a cheap non-atomic increment operation... and moving to multithread is as simple as swapping Arc
for Rc
.
来源:https://stackoverflow.com/questions/42097611/how-can-i-better-store-a-string-to-avoid-many-clones