2017-12-28 48 views
0

벡터 a이 있는데이 벡터의 조각을 복제해야합니다 (예 : a[n..n+3], k 번). 예를 들어벡터 조각을 다른 벡터로 복제하는 방법은 무엇입니까?

:

a = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
n = 2 
k = 3 

는 내가 생성하고 싶습니다 :

b = vec![2, 3, 4, 2, 3, 4, 2, 3, 4] 

을 나는 결국 다음에 도착 일부 이전의 도움으로 :

a[n..n+3].iter().cloned().cycle().take(3 * k).collect() 

것은이 될 것이라고 녹 자립? 이것을하는 더 좋은 방법이 있습니까?

답변

1
좋아

, 그래서이 Which is more idiomatic? Functional, imperative or a mix? 을 읽고

 

    #![feature(test)] 
    extern crate test; 

    use test::Bencher; 

    #[bench] 
    fn bench_target_func(b: &mut Bencher) { 
     let a = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 
     let n = 2; 
     let k = 3; 
     b.iter(|| { 
      let b: Vec = a[n..n+3].iter().cloned().cycle().take(3 * k).collect(); 
     }); 
    } 

    #[bench] 
    fn bench_target_imper(b: &mut Bencher) { 
     let a = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 
     let n = 2; 
     let k = 3; 
     b.iter(|| { 
      let mut b: Vec = Vec::with_capacity(k * 3); 
      let mut it = a[n..n+3].iter().cloned().cycle(); 
      for _ in 0..k*3 { 
       b.push(it.next().unwrap()); 
      } 
     }); 
    } 

    #[bench] 
    fn bench_target_imper2(b: &mut Bencher) { 
     let a = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 
     let n = 2; 
     let k = 3; 

     b.iter(|| { 
      let mut b = Vec::with_capacity(3 * k); 
      for _ in 0..k { 
       b.extend_from_slice(&a[n..n + 3]); 
      } 
     }); 
    } 

    #[bench] 
    fn bench_target_func2(b: &mut Bencher) { 
     let a = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 
     let n = 2; 
     let k = 3; 

     b.iter(|| { 
      let b : Vec = (0..k).flat_map(|_| a[n..n+3].iter().cloned()).collect(); 
     }); 
    } 

    fn main() { 
     println!("Hello, world!"); 
    } 

아래 벤치 마크를 실행 한 후 나는 다음과 같은 결과를 얻었다 : 그 flat_map가 훨씬 느립니다

 

    test bench_target_func ... bench:   31 ns/iter (+/- 0) 
    test bench_target_func2 ... bench:   97 ns/iter (+/- 1) 
    test bench_target_imper ... bench:   37 ns/iter (+/- 0) 
    test bench_target_imper2 ... bench:   29 ns/iter (+/- 0) 

나타납니다. 나에게

+0

그래서,이게 관용적 인 녹이겠습니까? – Roxy

+0

감사합니다. 기능 버전이 매우 읽기 쉽고 빠르다고 보입니다. 차라리 몇 가지 영향을 받아 깨끗한 코드를 얻으려고합니다. – Roxy

+0

'bench_target_imper'는 작업량을 3 배 줄입니다. 'for 0..k'는'for 0. 0.k * 3'이어야합니다. – red75prime

0

는 예를 충분히 녹 관용적 것 같다,하지만 난 이런 짓을 했을까 :

let a = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 
let n = 2; 
let k = 3; 

let b : Vec<_> = (0..k).flat_map(|_| a[n..n+3].iter().cloned()).collect(); 
println!("{:?}", b); 

나는 또한 어떤 경우에 유용 할 수있는 다음 자세한 방법을 제안한다.

let a = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 
let n = 2; 
let k = 3; 

let mut b = Vec::with_capacity(3 * k); 
for _ in 0..k { 
    b.extend_from_slice(&a[n..n+3]); 
} 
println!("{:?}", b);