简体   繁体   English

获取多个整数用户输入并将其存储在 Vec 中的最有效方法是什么<i32> ?

[英]What is the most efficient way of taking a number of integer user inputs and storing it in a Vec<i32>?

I was trying to use rust for competitive coding and I was wondering what is the most efficient way of storing user input in a Vec.我试图使用 rust 进行竞争性编码,我想知道在 Vec 中存储用户输入的最有效方法是什么。 I have come up with a method but I am afraid that it is slow and redundant.我想出了一个方法,但我担心它很慢而且多余。

Here is my code:这是我的代码:

use std::io;

fn main() {
  let mut input = String::new();
  io::stdin().read_line(&mut input).expect("cant read line");
  let input:Vec<&str> = input.split(" ").collect();
  let input:Vec<String> = input.iter().map(|x| x.to_string()).collect();
  let input:Vec<i32> = input.iter().map(|x| x.trim().parse().unwrap()).collect();
  println!("{:?}", input);
}

PS: I am new to rust. PS:我是生锈的新手。

I see those ways of improving performance of the code:我看到了提高代码性能的那些方法:

  1. Although not really relevant for std::io::stdin() , std::io::BufReader may have great effect for reading eg from std::fs::File .虽然与std::io::stdin()并不真正相关,但std::io::BufReader可能对从std::fs::File读取例如有很大的影响。 Buffer capacity can also matter.缓冲容量也很重要。
  2. Using locked stdin: let si = std::io::stdin(); let si = si.locked();使用锁定的标准输入: let si = std::io::stdin(); let si = si.locked(); let si = std::io::stdin(); let si = si.locked();
  3. Avoiding allocations by keeping vectors around and using extend_from_iter instead of collect , if the code reads multiple line (unlike in the sample you posted in the question).如果代码读取多行(与您在问题中发布的示例不同),则通过保留向量并使用extend_from_iter而不是collect来避免分配。
  4. Maybe avoiding temporary vectors alltogether and just chaining Iterator operations together.也许一起避免临时向量,只是将Iterator操作链接在一起。 Or using a loop like for line in input.split(...) { ... } .或者for line in input.split(...) { ... }的循环。 It may affect performance in both ways - you need to experiment to find out.它可能会以两种方式影响性能 - 您需要进行试验才能找到答案。
  5. Avoiding to_string() and just storing reference to input buffer (which can also be used to parse() into i32 . Note that this may invite famous Rust borrowing and lifetimes complexity.避免to_string()并仅存储对输入缓冲区的引用(也可用于parse()i32中。请注意,这可能会导致著名的 Rust 借用和生命周期复杂性。
  6. Maybe finding some fast SIMD-enhanced string to int parser instead of libstd's parse() .也许找到一些快速的 SIMD 增强字符串到 int 解析器而不是 libstd 的parse()
  7. Maybe streaming the result to algorithm instead of collecting everything to a Vec first.也许将结果流式传输到算法,而不是先将所有内容收集到Vec This can be beneficial especially if multiple threads can be used.这可能是有益的,尤其是在可以使用多个线程的情况下。 For performance, you would still likely need to send data in chunks, not by one single i32 .为了提高性能,您仍然可能需要分块发送数据,而不是单个i32

Yeah, there are some changes you can make that will make your code more precise, simple and faster.是的,您可以进行一些更改,以使您的代码更加精确、简单和快速。

A better code :更好的代码:

use std::io;

fn main() {
  let mut input = String::new();
  io::stdin().read_line(&mut input).unwrap();

  let input: Vec<i32> = input.split_whitespace().map(|x| x.parse().unwrap()).collect();

  println!("{:?}", input);
}

Explanation解释

  1. The input.split_whitespace() returns an iterator containing elements that are seperated by any kind of whitespace including line breaks. input.split_whitespace()返回一个迭代器,其中包含由任何类型的空格(包括换行符)分隔的元素。 This saves the time used in spliting by just one whitespace input.split(" ") and iterating over again with a .trim() method on each string slice to remove any surronding whitespaces.这节省了仅用一个空格input.split(" ")进行拆分的时间,并在每个字符串切片上使用.trim()方法再次迭代以删除任何周围的空格。 (You can also checkout input.split_ascii_whitespace() , if you want to restrict the split over ascii whitespaces). (如果您想限制对 ascii 空格的拆分,您也可以签input.split_ascii_whitespace() )。

  2. There was no need for the code input.iter().map(|x| x.to_string()).collect() , since you can call also call a .trim() method on a string slice.不需要代码input.iter().map(|x| x.to_string()).collect() ,因为您也可以在字符串切片上调用.trim()方法。

This saves some time in both the runtime and coding process, since the .collect() method is only used once and there was just one iteration.这在运行时和编码过程中都节省了一些时间,因为.collect()方法只使用一次并且只有一次迭代。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 vec 和有什么区别<i32>和 Vec <Box<i32> &gt;? - What is the difference between Vec<i32> and Vec<Box<i32>>? 为什么我在使用FlatMap迭代器时没有为Vec <i32>实现错误FromIterator <&{integer}>? - Why do I get the error FromIterator<&{integer}> is not implemented for Vec<i32> when using a FlatMap iterator? 我如何通过Vec <Vec<i32> &gt;功能? - How do I pass a Vec<Vec<i32>> to a function? 退回Rust Vec <Vec<i32> &gt;通过WebAssembly转换为JavaScript - Returning a Rust Vec<Vec<i32>> to JavaScript via WebAssembly 错误类型不匹配:预期的&#39;collections :: vec :: Vec <i32> &#39;,找到了&#39;&collections :: vec :: Vec <i32> &#39; - Error mismatched types: expected 'collections::vec::Vec<i32>', found '&collections::vec::Vec<i32>' 在文件中存储 i32 的原生、惯用和安全方式是什么? - What is the native, idiomatic, and safe way to store an i32 in a file? 我怎样才能建立一个`Vec<i32> ` 来自 `Iterator<item=&i32> `?</item=&i32></i32> - How can I build a `Vec<i32>` from an `Iterator<Item=&i32>`? 如何转换Vec <i32> 到类型:: array :: ArrayBase <Option<i32> &gt;对于锈postgres? - How to convert Vec<i32> to types::array::ArrayBase<Option<i32>> for rust-postgres? 在这种情况下借来的价值不够长(Vec &lt;&Fn(i32) - &gt; i32&gt;) - borrowed value does not live long enough in this case ( Vec<&Fn(i32) -> i32> ) 我应该如何用i32调用Vec :: with_capacity? - How should I call Vec::with_capacity with an i32?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM