From 830bac554898fa6e3969876134324df4b41670c1 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Wed, 9 Aug 2023 14:00:06 +0200 Subject: [PATCH 1/3] clarify why `Vec::new()` + resize is worse than `vec![0; N]` --- clippy_lints/src/slow_vector_initialization.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 54a33eb2986d..2117bcae22cb 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -20,6 +20,20 @@ declare_clippy_lint! { /// These structures are non-idiomatic and less efficient than simply using /// `vec![0; len]`. /// + /// More specifically, for `vec![0; len]`, the compiler can use a more specialized type of allocation + /// that also zero-initializes the allocated memory in the same call + /// (see: [alloc_zeroed](https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#method.alloc_zeroed)). + /// + /// Writing `Vec::new()` followed by `vec.resize(len, 0)` is suboptimal because, + /// while it does do the same number of allocations, + /// it involves two operations for allocating and initializing. + /// The `resize` call first allocates memory (since `Vec::new()` did not), and only *then* zero-initializes it. + /// + /// Writing `Vec::with_capacity(size)` followed by `vec.resize(len, 0)` is similar. + /// The allocation shifts from `resize` to `with_capacity`, + /// but the zero-initialization still happens separately, + /// when it could be done in one call with `vec![0; len]` (`alloc_zeroed`). + /// /// ### Example /// ```rust /// # use core::iter::repeat; @@ -32,6 +46,9 @@ declare_clippy_lint! { /// /// let mut vec2 = Vec::with_capacity(len); /// vec2.extend(repeat(0).take(len)); + /// + /// let mut vec3 = Vec::new(); + /// vec3.resize(len, 0); /// ``` /// /// Use instead: @@ -39,6 +56,7 @@ declare_clippy_lint! { /// # let len = 4; /// let mut vec1 = vec![0; len]; /// let mut vec2 = vec![0; len]; + /// let mut vec3 = vec![0; len]; /// ``` #[clippy::version = "1.32.0"] pub SLOW_VECTOR_INITIALIZATION, From d2acfb37b3344de3405457e02c4703cfc74bcb95 Mon Sep 17 00:00:00 2001 From: Timo <30553356+y21@users.noreply.github.com> Date: Wed, 9 Aug 2023 14:44:42 +0200 Subject: [PATCH 2/3] Reword paragraph Co-authored-by: Dirkjan Ochtman --- clippy_lints/src/slow_vector_initialization.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 2117bcae22cb..1001441b03d5 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -20,7 +20,7 @@ declare_clippy_lint! { /// These structures are non-idiomatic and less efficient than simply using /// `vec![0; len]`. /// - /// More specifically, for `vec![0; len]`, the compiler can use a more specialized type of allocation + /// Specifically, for `vec![0; len]`, the compiler can use a specialized type of allocation /// that also zero-initializes the allocated memory in the same call /// (see: [alloc_zeroed](https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#method.alloc_zeroed)). /// From dd25cc349be3dae9b7c7f1ad0465ab14fab773e3 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Wed, 9 Aug 2023 14:48:31 +0200 Subject: [PATCH 3/3] Remove unnecessary paragraph, move examples --- clippy_lints/src/slow_vector_initialization.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 1001441b03d5..c9ab622ad25d 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -29,26 +29,18 @@ declare_clippy_lint! { /// it involves two operations for allocating and initializing. /// The `resize` call first allocates memory (since `Vec::new()` did not), and only *then* zero-initializes it. /// - /// Writing `Vec::with_capacity(size)` followed by `vec.resize(len, 0)` is similar. - /// The allocation shifts from `resize` to `with_capacity`, - /// but the zero-initialization still happens separately, - /// when it could be done in one call with `vec![0; len]` (`alloc_zeroed`). - /// /// ### Example /// ```rust /// # use core::iter::repeat; /// # let len = 4; - /// let mut vec1 = Vec::with_capacity(len); + /// let mut vec1 = Vec::new(); /// vec1.resize(len, 0); /// - /// let mut vec1 = Vec::with_capacity(len); - /// vec1.resize(vec1.capacity(), 0); - /// /// let mut vec2 = Vec::with_capacity(len); - /// vec2.extend(repeat(0).take(len)); + /// vec2.resize(len, 0); /// - /// let mut vec3 = Vec::new(); - /// vec3.resize(len, 0); + /// let mut vec3 = Vec::with_capacity(len); + /// vec3.extend(repeat(0).take(len)); /// ``` /// /// Use instead: