对不可变数组切片的引用的反向顺序

Hag*_*aiH 1 rust borrow-checker

我想颠倒切片的顺序:

&[1, 2, 3] -> &[3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

fn iterate_over_file(data: &[u8], ...) -> ... {
    ...
    for cur_data in data.chunks(chunk_size) {
         let reversed_cur_data = cur_data.reverse() // this returns ()
         ...
    ...
 }
Run Code Online (Sandbox Code Playgroud)

这个data参数来自我读过的文件FileBuffer,我想把它作为一个引用的片段(而不是把它变成一个拥有的Vec,因为它是一个繁重的计算).

如何cur_data以最少的操作和内存分配来颠倒顺序?它的长度以我的程序的特定运行时(在此处称为chunk_size)而闻名,但它在不同的运行之间发生变化.reversed()似乎返回(),这是有道理的,因为它是就地完成的,我只有一个引用的切片..iter().rev()创建一个迭代器,但是我必须多次调用.next()它来获得切片,这既不优雅又无效,因为cur_data每个文件至少有数千万行.

use*_*342 5

不仅reverse返回(),它还需要一个你没有的可变切片.最佳解决方案完全取决于您需要对数据执行的操作.如果您只需要迭代数据,那么这cur_data.iter().rev()是正确且最有效的选择.

如果您需要切片内的反转数据,进行进一步处理,或将反转的块发送到需要切片的函数,您可以将数据收集到一个向量中,该向量在循环迭代之间预先分配和共享以避免分配对于每个块:

let mut reversed = Vec::new();
for cur_data in data.chunks(chunk_size) {
     // truncate the slice at the beginning of each iteration.
     // Vec explicitly guarantees that this will *not* deallocate,
     // it will only reset its internal length. An allocation will
     // thus happen only at the first loop iteration.
     reversed.truncate(0);
     reversed.extend(cur_data.iter().rev());
     // &reversed is now the reversed_cur_data you need
     ...
}
Run Code Online (Sandbox Code Playgroud)

  • @Shepmaster我有完全相反的感觉:)所以我决定测量.在我的机器上,[this](https://pastebin.com/MtH0MYd7)执行时需要~1.02秒,同时切换到`v.extend(); v.rev()`需要~1.25秒.(使用`extend_from_slice()`没有区别.)看来我的预感是正确的,至少在当前的编译器中是这样. (2认同)