@@ -462,20 +462,47 @@ impl<T, const N: usize> [T; N] {
462462 ///
463463 /// # Note on performance and stack usage
464464 ///
465- /// Unfortunately, usages of this method are currently not always optimized
466- /// as well as they could be. This mainly concerns large arrays, as mapping
467- /// over small arrays seem to be optimized just fine. Also note that in
468- /// debug mode (i.e. without any optimizations), this method can use a lot
469- /// of stack space (a few times the size of the array or more).
470- ///
471- /// Therefore, in performance-critical code, try to avoid using this method
472- /// on large arrays or check the emitted code. Also try to avoid chained
473- /// maps (e.g. `arr.map(...).map(...)`).
474- ///
475- /// In many cases, you can instead use [`Iterator::map`] by calling `.iter()`
476- /// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you
477- /// really need a new array of the same size as the result. Rust's lazy
478- /// iterators tend to get optimized very well.
465+ /// Note that this method is *eager*. In terms of `Iterator` methods, it's
466+ /// more like `.map(…).collect()`, since it returns a new array.
467+ ///
468+ /// That means that `arr.map(f).map(g)` is, in general, *not* equivalent to
469+ /// `array.map(|x| g(f(x)))`, as the former calls `f` 4 times then `g` 4 times,
470+ /// whereas the latter interleaves the calls (`fgfgfgfg`).
471+ ///
472+ /// A consequence of this is that it can have fairly-high stack usage, especially
473+ /// in debug mode or for long arrays. The backend may be able to optimize it
474+ /// away, but especially for complicated mappings it might not be able to.
475+ ///
476+ /// If you're doing a one-step `map` and really want an array as the result,
477+ /// then absolutely use this method. Its implementation uses a bunch of tricks
478+ /// to help the optimizer handle it well.
479+ ///
480+ /// However, in many cases you can instead use [`Iterator::map`] by calling
481+ /// `.iter()` or `.into_iter()` on your array. Rust's lazy iterators tend to
482+ /// get optimized very well.
483+ ///
484+ /// For example, rather than doing an array-to-array map of all the elements
485+ /// in the array up-front and only iterating after that completes,
486+ ///
487+ /// ```
488+ /// # let my_array = [1, 2, 3];
489+ /// # let f = |x: i32| x + 1;
490+ /// for x in my_array.map(f) {
491+ /// // ...
492+ /// }
493+ /// ```
494+ ///
495+ /// It's often better to use a lazy iterator map like this
496+ ///
497+ /// ```
498+ /// # let my_array = [1, 2, 3];
499+ /// # let f = |x: i32| x + 1;
500+ /// for x in my_array.into_iter().map(f) {
501+ /// // ...
502+ /// }
503+ /// ```
504+ ///
505+ /// so that the elements are mapped-then-processed one at a time instead.
479506 ///
480507 ///
481508 /// # Examples
0 commit comments