-
Notifications
You must be signed in to change notification settings - Fork 308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add zip_clones
, zips an iterator with clones of a value
#989
base: master
Are you sure you want to change the base?
Conversation
Similar to `iter.zip(repeat_n(val, n))' but does not require knowing n
Hi there, foremost: Thanks for this. Honestly, I don't believe that is sufficiently useful to justify an own implementation. Is the intention to avoid the If my assumptions are correct, I personally would advise against inclusion of this. Aside: Couldn't the |
I think it is useful in many use cases, take for example mine: Avoiding the clone is not relevant only in zip contexts, but its the smoother way to clone something Thanks for the comment regarding |
Hm... I hope I don't miss the forest for the trees, but I am not convinced. Maybe @jswrenn or @Philippe-Cholet groks your examples. Could you share a boiled down version of your use case to show why |
Here is a boiled down version of my use case: #[derive(Clone)]
struct Data {
values: Vec<f64>,
metadata_field1: usize,
metadata_field2: usize,
// ...
}
struct Component {
inputs: Vec<Receiver<Data>>,
outputs: Vec<Sender<Data>>,
}
impl Component {
fn component_main(&self) {
let mut sel = Select::new();
for input in self.inputs.iter() {
sel.recv(input);
}
loop {
let oper = sel.select();
let idx = oper.index();
let data = oper.recv(&self.inputs[idx]).unwrap();
let result = self.process_data(data);
for output in self.outputs.iter() {
output.send(result.clone()).unwrap();
}
}
}
fn process_data(&self, data: Data) -> Data {
unimplemented!()
}
} Each The above implementation use a trivial approach cloning the result for each output. for output in self.outputs.iter() {
output.send(result.clone()).unwrap();
} Given a for (output, result) in self.outputs.iter().zip_clones(result) {
output.send(result).unwrap();
} Without such a method, you could implement it as follows: if !self.outputs.is_empty() {
for output in self.outputs[..self.outputs.len() - 1].iter() {
output.send(result.clone()).unwrap();
}
self.outputs[self.outputs.len() - 1].send(result).unwrap();
} The above relay on the fact the outputs are stored in a vector, as we must know the number of outputs. let mut outputs = self.outputs.iter();
let mut cur = outputs.next();
if cur.is_some() {
let mut next = outputs.next();
while next.is_some() {
cur.unwrap().send(result.clone()).unwrap();
cur = next;
next = outputs.next();
}
cur.unwrap().send(result).unwrap();
} To emphasise, I want to avoid the last clone because many times a component is connected to only one other component, namely it has a single output, and no allocation should be done at all. Even for cases in which I have few outputs, the data packets are flowing in high frequencies and the last clone is redundant. |
Similar to `iter.zip(repeat_n(val, n))' but does not require knowing n