Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 重复(x)。采取(n)执行吗?_Performance_Rust - Fatal编程技术网

Performance 重复(x)。采取(n)执行吗?

Performance 重复(x)。采取(n)执行吗?,performance,rust,Performance,Rust,我正在寻找一种有效的方法来编写以下函数,如中所述: Rust是否为泛型结构类型的实例生成具体类型?是重复('.')的结果。take(n)(结构take)等效于 struct Take_Repeat_char { element: char, n: usize } 方法实现是否内联?是否有一个版本的Take::next()内联了Repeat::next() 什么是我自己检查这个的好方法?检查LLVM IR?是的,这是生锈的™ 足够地是的,如果您使用优化编译(例如,cargo bu

我正在寻找一种有效的方法来编写以下函数,如中所述:

Rust是否为泛型结构类型的实例生成具体类型?是重复('.')的结果。take(n)(结构
take
)等效于

struct Take_Repeat_char {
    element: char,
    n: usize
}
方法实现是否内联?是否有一个版本的
Take::next()
内联了
Repeat::next()


什么是我自己检查这个的好方法?检查LLVM IR?

是的,这是生锈的™ 足够地是的,如果您使用优化编译(例如,
cargo build--release
),LLVM将嵌入整个过程。检查过孔并查看生成的部件。有关守则是:

movb    $46, (%rax)
movb    $46, 1(%rax)
movb    $46, 2(%rax)
movb    $46, 3(%rax)
movb    $46, 4(%rax)
五个点。我相信将前四个点合并成一个点可能会更快

movd    $x2e2e2e2e, (%rax)
指导,但我认为这不会有多大区别。编辑:实际上取决于内存对齐方式,它可能快一些,也可能慢一些:如果对齐了
%rax
,它可能会快一些(取决于缓存、预取等复杂的事情),否则它可能会慢一些(因为可能存在陷阱)

Rust是否为泛型结构类型的实例生成具体类型

是的,这叫做单晶化

方法实现是内联的吗

像许多语言一样,这是一个坚实的“也许”。有两种方法可以控制内部和内部的内联,但通常由编译器来做正确的事情。如上所述,如果一个函数使用泛型类型,它将自动用于单组化,这意味着内联它所需的信息可以在编译的板条箱中获得

什么是我自己检查这个的好方法

许多人将使用来查看LLVM IR或程序集。当然,您可以使用
rustc--emit[asm | llvm ir]
在本地查看它。在执行此操作时,我将感兴趣的代码放在一个永远不会内联的函数中。这使得在assembly/IR输出中更容易找到:

#[inline(never)]
fn dots(n: usize) -> String {
    std::iter::repeat('.').take(n).collect()
}
正如前面所指出的,rustc和LLVM已经看穿了您的整个实现,并完全展开了它。不过,实现会根据需要的字符数进行更改

要知道它是否快,唯一的方法是分析它的轮廓。引用llogiq:

我相信将前四个点合并成一个
movd

我主张在现实世界中测试任何这样的代码。程序集非常重要,尤其是x64/x86_64变体。指令可能有奇怪的管道要求,或者可能导致CPU的其他部分不可用


简介,简介,简介^_^

这不是真正的表演,有点糟糕

const CAP: usize = 64 * 1024;

#[bench]
fn fill_string_repeat(b: &mut Bencher) {
    b.iter(|| {
        repeat('.').take(CAP).collect::<String>()
    });
    b.bytes = CAP as u64;
}

#[bench]
fn fill_string_vec(b: &mut Bencher) {
    b.iter(|| {
        String::from_utf8(vec![b'.'; CAP])
    });
    b.bytes = CAP as u64;
}
vec解决方案要好得多,这包括占主导地位的UTF-8检查开销,使用
String::from\u utf8\u unchecked
并获得:

test fill_string_vec_unchecked       ... bench:      29,354 ns/iter (+/- 503) = 2232 MB/s

(这里基本上只保留了memset。)

我不得不使用-1,因为它的性能不够。我们不能简单地重复“iterator inline great”(他们确实这么做)这句话来激发像“它优化到了好代码”这样的结论,这是不正确的。改进了
BufWriter
construction:@bluss:fair够了——请注意,我并没有说这在所有情况下都有效,只是针对给定的特定示例。真的。内联的
点(5)
看起来不错,你举了一个很好的例子,我用另一个不太好的例子回答。我认为重要的一点是,
repeat().take()
并不总是产生最好的代码。我们可以说“足够好的编译器”还没有出现。内置于发布模式?
test fill_string_repeat              ... bench:     240,467 ns/iter (+/- 719) = 272 MB/s
test fill_string_vec                 ... bench:     106,885 ns/iter (+/- 224) = 613 MB/s
test fill_string_vec_unchecked       ... bench:      29,354 ns/iter (+/- 503) = 2232 MB/s