Suggest an editImprove this articleRefine the answer for “Array methods vs loops”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)Array methods (`map`, `filter`, `forEach`, `reduce`, and so on) are **abstractions over loops**, implemented inside the JavaScript engine. **Key point:** they are more convenient, shorter, and more readable, but carry extra overhead (calling a callback on every iteration, creating a new array, validation), so they can be slower than plain loops (`for`, `for...of`, `while`), especially on large arrays.Shown above the full answer for quick recall.Answer (EN)Image## 1. In short: what's going on Array methods (`map`, `filter`, `forEach`, `reduce`, and so on) are **abstractions over loops**, implemented inside the JavaScript engine. They're more convenient, shorter, and more readable, but **they carry extra overhead**, which is why they can be **slower than plain loops (**`for`**,** `for…of`**,** `while`**)**, especially on large arrays. --- ## 2. What happens "under the hood" When you write: ```javascript arr.map(x => x * 2); ``` the engine does roughly the following: 1. Checks that `arr` is actually an array. 2. Creates a **new array** for the results. 3. On every iteration: - calls the **callback function**; - passes it three arguments `(element, index, array)`; - stores the result in the new array. 4. Returns the resulting array. That's a bunch of steps that **add overhead**, compared to a plain `for` loop, where you just run instructions with no wrappers or checks. --- ## 3. Why it's actually slower | Reason | What happens | |---|---| | **Callback function** | A new function is called on every iteration -> extra call-stack frames | | **Creating a new array** | `map`, `filter`, `slice`, `concat` create copies (extra memory) | | **Checks and context** | The method runs through validations (length, holes, prototype, type) | | **Unoptimized closures** | If the callback captures outer variables, that's even more overhead | | **Functional principles** | These methods are "pure" and don't mutate data -> more allocations are needed | | **Loops are easier for the JIT compiler to optimize** | The engine (V8, SpiderMonkey) optimizes a "bare" `for` faster | --- ## 4. A comparison example ```javascript const arr = Array.from({ length: 1_000_000 }, (_, i) => i); // map console.time('map'); const doubled1 = arr.map(x => x * 2); console.timeEnd('map'); // for console.time('for'); const doubled2 = new Array(arr.length); for (let i = 0; i < arr.length; i++) { doubled2[i] = arr[i] * 2; } console.timeEnd('for'); ``` On most engines the result looks roughly like this: ```javascript map: 30-60 ms for: 10-20 ms ``` The difference is small on small data, but with millions of elements, `for` is **2-5 times** faster. --- ## 5. Why this is especially noticeable in "hot" code paths > If a loop runs millions of times (rendering, sorting, data aggregation, parsing), > callback overhead starts to "cost real time". In such places: - every callback call is a new call-stack frame; - extra allocations mean more GC (garbage collector) work; - extra arguments (`index`, `array`) mean more objects in memory. --- ## 6. When it **doesn't matter** For **most business tasks** (lists, filters, mapping up to 10k elements): - the difference between `for` and `map` is **fractions of a millisecond**; - readability and clean code **matter more**. That's why React/Vue code uses `.map()` for JSX, because it's declarative and clear: ```javascript {items.map(item => <Card key={item.id} {...item} />)} ``` But if you have an array of **millions of elements** or a loop in a "hot path" (rendering, binary data processing, canvas, a parser), it's better to use: ```javascript for (let i = 0; i < n; i++) ... ``` --- ## 7. What's actually faster (in order) | Loop | Speed | Notes | |---|---|---| | `for (let i = 0; i < n; i++)` | The fastest | No checks, inline, predictable | | `for...of` | Fast, but uses an iterator | A little overhead | | `while` | About the same | Almost like `for`, depends on the engine | | `forEach()` | Slower (callback) | Doesn't return a new array | | `map()` | Slower, creates a new array | | | `filter()`, `reduce()` | Even slower | Allocations, extra operations | --- ## 8. How to speed up array methods | Method | Optimization | |---|---| | `.map()` | Use a pure arrow function inside it, with no outer closures | | `.filter()` | Don't chain `.map().filter().reduce()`, merge into one loop | | `.reduce()` | For complex operations, move the accumulation into a `for` | | `.forEach()` | Replace with `for` or `for...of` in "hot" code | | `.concat()` / spread (`[...a, ...b]`) | Replace with `push.apply()` or a loop for large arrays | --- ## 9. Brief summary | Reason | Why it's slower | |---|---| | Callback functions | create extra calls and context | | A new array | new memory is allocated | | Validation and iteration | built-in checks and protocols | | GC load | temporary objects are created | | Loops are more primitive | easier for the JIT compiler to optimize | > Conclusion: > > - For **performance-critical** tasks -> `for`. > - For **clear, declarative code** -> `map`, `filter`, `reduce`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.