Skip to content

Commit

Permalink
更新到hashing.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Blues-star committed Feb 28, 2024
1 parent 0b15c98 commit 061c21a
Show file tree
Hide file tree
Showing 7 changed files with 362 additions and 106 deletions.
19 changes: 19 additions & 0 deletions history.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
modified: .github/workflows/ci.yml
modified: .gitignore
modified: src/benchmarking.md
new file: src/bounds-checks.md
modified: src/build-configuration.md
modified: src/compile-times.md
modified: src/general-tips.md
modified: src/hashing.md
modified: src/heap-allocations.md
modified: src/inlining.md
modified: src/introduction.md
modified: src/io.md
modified: src/iterators.md
modified: src/linting.md
modified: src/logging-and-debugging.md
modified: src/machine-code.md
modified: src/profiling.md
modified: src/standard-library-types.md
modified: src/type-sizes.md
25 changes: 17 additions & 8 deletions src/benchmarking_zh.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
# Benchmarking

在优化一个程序时,你需要一种方法来可靠地回答 "这个改变是否加快了程序?"这个问题。这个过程有时被称为基准测试(benchmarking)。基准测试是一个复杂的话题,彻底的覆盖范围超出了本书的范围,但以下是基本的内容。
基准测试通常涉及比较执行相同任务的两个或多个程序的性能。有时可能涉及比较两个或多个不同的程序,例如 `Firefox` vs `Safari` vs `Chrome`。有时涉及比较同一程序的两个不同版本。后一种情况让我们能够可靠地回答问题“这个变化是否加快了速度?”

首先,你需要工作负载来衡量。理想情况下,你会有各种工作负载,代表你的程序的实际使用情况。使用真实世界输入的工作负载是最好的,但[microbenchmarks][压力测试(stress tests)]在适度的情况下也是有用的。
基准测试是一个复杂的主题,全面覆盖超出了本书的范围,但以下是基础知识。

首先,您需要工作负载来进行测量。理想情况下,您会有各种代表程序实际使用情况的工作负载。使用真实世界输入的工作负载最好,但[microbenchmarks][压力测试]在适度的情况下也是有用的。

[microbenchmarks]: https://stackoverflow.com/questions/2842695/what-is-microbenchmarking
[压力测试(stress tests)]: https://en.wikipedia.org/wiki/Stress_testing_(software)
[压力测试]: https://en.wikipedia.org/wiki/Stress_testing_(software)

其次,您需要一种运行工作负载的方式,这也将决定所使用的度量标准。

其次,你需要一种运行工作负载的方法,这也将决定使用的指标。Rust内置的[基准测试(benchmark tests)]是一个简单的起点。[Criterion]是一个更复杂的选择。自定义benchmarking harnesses也是可能的。例如,[rustc-perf]就是用来对Rust编译器进行基准测试的harnesses。
Rust 内置的[benchmark tests]是一个简单的起点,但它们使用不稳定的功能,因此仅适用于夜间版的 Rust。
[Criterion][Divan] 是更复杂的替代方案。
[Hyperfine] 是一个出色的通用基准测试工具。
也可以使用自定义基准测试工具。例如,[rustc-perf] 是用于对 Rust 编译器进行基准测试的工具。

[基准测试(benchmark tests)]: https://doc.rust-lang.org/1.7.0/book/benchmark-tests.html
[benchmark tests]: https://doc.rust-lang.org/nightly/unstable-book/library-features/test.html
[Criterion]: https://github.com/bheisler/criterion.rs
[Divan]: https://github.com/nvzqz/divan
[Hyperfine]: https://github.com/sharkdp/hyperfine
[rustc-perf]: https://github.com/rust-lang/rustc-perf/

当涉及到度量时,有许多选择,正确的选择将取决于被基准化的程序的性质。例如,对批处理程序有意义的指标可能对交互式程序没有意义。在许多情况下,Wall-time是一个显而易见的选择,因为它与用户的感知相对应。然而,它可能会受到大幅变化的影响。特别是,内存布局的微小变化可能会导致显著但短暂的性能波动。因此,方差较小的其他指标(如周期或指令数)可能是一个合理的选择
在度量标准方面,有许多选择,选择合适的度量标准取决于正在进行基准测试的程序的性质。例如,对于`批处理程序`(batch program)有意义的度量标准可能对`交互式程序`(interactive program)没有意义。在许多情况下,`Wall-time`是一个显而易见的选择,因为它对应于用户的感知。然而,它可能受到高方差的影响。特别是,内存布局中微小的变化可能导致显著但短暂的性能波动。因此,具有较低方差的其他度量标准(如周期cycles或指令计数)可能是一个合理的替代方案

从多个工作负载中总结测量结果也是一个挑战,尽管有多种方法,但并没有一种方法是最完美的
总结来自多个工作负载的测量结果也是一个挑战,有许多方法可以做到这一点,没有一种方法显然是最好的

良好好的基准测试是很难实现的。总而言之,不要过于强调拥有一个完美的基准测试设置,特别是当你开始优化一个程序的时候。一个平庸的设置比没有设置要好得多。对你正在测量的东西保持开放的心态,随着时间的推移,你可以在了解你的程序的性能特点后进行基准测试改进
良好的基准测试很困难。话虽如此,在拟进行程序优化时,不要过分强调拥有完美的基准测试设置,尤其是在开始优化程序时。一般的基准测试要比没有基准测试好得多。保持对您正在测量的内容开放的态度,随着时间的推移,您可以根据了解到的程序性能特征进行基准测试改进

21 changes: 21 additions & 0 deletions src/bounds-checks_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Bounds Checks

默认情况下,在 Rust 中,对切片和向量等容器类型的访问涉及边界检查。这可能会影响性能,例如在热循环中,尽管发生的频率可能不如您所预期的那样频繁。

有几种安全的方法可以更改代码,以便编译器了解容器的长度并优化掉边界检查。

- 在循环中,通过迭代替换直接元素访问。
- 在循环中,不要对 Vec 进行索引,而是在循环之前创建 Vec 的切片,然后在循环中对切片进行索引。
- 在索引变量的范围上添加断言。
[**Example 1**](https://github.com/rust-random/rand/pull/960/commits/de9dfdd86851032d942eb583d8d438e06085867b),
[**Example 2**](https://github.com/image-rs/jpeg-decoder/pull/167/files).

让这些方法起作用可能有些棘手。[Bounds Check Cookbook]对这个主题进行了更详细的介绍

[Bounds Check Cookbook]: https://github.com/Shnatsel/bounds-check-cookbook/

作为最后的手段,还有不安全的方法 [get_unchecked][get_unchecked_mut]

[`get_unchecked`]: https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked
[`get_unchecked_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked_mut

Loading

0 comments on commit 061c21a

Please sign in to comment.