# How to unroll for loop

**URL:** <https://ziggit.dev/t/how-to-unroll-for-loop/15078>\
**Category:** Help\
**Tags:** language\
**Created:** [April 20, 2026, 8:43pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078 "2026-04-20T20:43:59Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![markus](https://ziggit.dev/letter_avatar_proxy/v4/letter/m/b782af/32.png) [@markus](https://ziggit.dev/u/markus)\
**Post date:** [April 20, 2026, 8:43pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/1 "2026-04-20T20:43:59Z")

</div>

Hello,  
I am trying to play around with a simple program and its performance and would like to unroll a for loop a certain number of times. Is this possible?

The reason for why I want to do it is that my friend did it in C and their program instantly became significantly faster.

Edit:  
I did try the manual unrolling via inline for (but without early breaks) and am once again faster hehe  
Edit2:  
Nevermind, I added the early returns to genuinely make the code equivalent and it’s now marginally slower than before. I am kinda out of obvious ideas. I _could_ try to do some simd things but not today.

---

<div class="post-metadata">

**Author:** ![Southporter](https://ziggit.dev/user_avatar/ziggit.dev/southporter/32/2500_2.png) [@Southporter](https://ziggit.dev/u/Southporter)\
**Post date:** [April 20, 2026, 8:56pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/2 "2026-04-20T20:56:14Z")

</div>

> [@markus](#):
>
> Is this possible?

Yes, if you can do it in C, you can probably do it in Zig.

Without knowing your code, I can try to explain the theory behind loop unrolling. You would have to apply it to your specific loop.

Say you have an array of 1000 items and you wanted to unroll it 4 times.

A normal zig loop would be:

```zig
for (some_items) |item| {
    // do something on that item
    const x = doSomething(item);
    result += x;
}

```

To unroll that loop, you would have to “batch” up the operations instead of one at a time.

```zig
for (0..@divExact(some_items.len, 4)) |offset| {
    const a = doSomething(some_items[offset]);
    const b = doSomething(some_items[offset + 1]);
    const c = doSomething(some_items[offset + 2]);
    const d = doSomething(some_items[offset + 3]);
    result += a + b + c + d;
}

```

That’s the theory anyway. As you can see, you can unroll it any number of times, but you will have to benchmark to see how much it helps in a given situation.

---

<div class="post-metadata">

**Author:** ![markus](https://ziggit.dev/letter_avatar_proxy/v4/letter/m/b782af/32.png) [@markus](https://ziggit.dev/u/markus)\
**Post date:** [April 20, 2026, 8:59pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/3 "2026-04-20T20:59:59Z")

</div>

Hm okay I had the same Idea, just thought I would nest loops and make the inner one an `inline for`, the reason why I stopped is because this forces me to include a bunch of early returns and the function itself is very cheap so I didn’t trust myself sufficiently to keep the calculating of indices at a minimum. I guess I’ll just try it out anyways.

This was kind of the reason I posted this, I thought “I wonder if there is an easier way that does this for me and may even leverage llvm”

---

<div class="post-metadata">

**Author:** ![Nae](https://ziggit.dev/user_avatar/ziggit.dev/nae/32/10157_2.png) [@Nae](https://ziggit.dev/u/Nae)\
**Post date:** [April 20, 2026, 9:03pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/4 "2026-04-20T21:03:04Z")

</div>

You could nest an `inline for` loop in a loop with bigger steps. To build on Southporter’s example:

```zig
const iteration_count = @divFloor(some_items.len, unroll_amount);
for (0..iteration_count) |iteration| {
    const start = iteration * unroll_amount;
    inline for (0..unroll_amount) |i| {
        const x = doSomething(some_items[start + i]);
        result += x;
    }
}
for (unroll_amount * iteration_count..some_items.len) |i| {
    const x = doSomething(some_items[i]);
    result += x;
}

```

Which lets you play with the unroll amount more easily.

edit: probably doesn’t work because `some_item`’s length is not comptime known.

edit2: updated snippet. See edit history for more embarassing versions.

---

<div class="post-metadata">

**Author:** ![markus](https://ziggit.dev/letter_avatar_proxy/v4/letter/m/b782af/32.png) [@markus](https://ziggit.dev/u/markus)\
**Post date:** [April 20, 2026, 9:03pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/5 "2026-04-20T21:03:32Z")

</div>

Thats basically Identical to my code before I gave up and made this post haha

---

<div class="post-metadata">

**Author:** ![Southporter](https://ziggit.dev/user_avatar/ziggit.dev/southporter/32/2500_2.png) [@Southporter](https://ziggit.dev/u/Southporter)\
**Post date:** [April 20, 2026, 9:04pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/6 "2026-04-20T21:04:59Z")

</div>

```diff
+ inline for (some_items[(offset * unroll_amount)..][0..unroll_amount]) |item| {
- inline for (some_items[offset..][0..unroll_amount]) |item| {

```

You have to make sure you update the offset correctly if you are going to batch them.

---

<div class="post-metadata">

**Author:** ![markus](https://ziggit.dev/letter_avatar_proxy/v4/letter/m/b782af/32.png) [@markus](https://ziggit.dev/u/markus)\
**Post date:** [April 20, 2026, 9:05pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/7 "2026-04-20T21:05:23Z")

</div>

But wouldnt this require early returns or modifying the data to include some “no-op equivalents” at the end?

---

<div class="post-metadata">

**Author:** ![Southporter](https://ziggit.dev/user_avatar/ziggit.dev/southporter/32/2500_2.png) [@Southporter](https://ziggit.dev/u/Southporter)\
**Post date:** [April 20, 2026, 9:06pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/8 "2026-04-20T21:06:08Z")

</div>

It depends on what your body looks like. For the examples of sum, then no. If you are trying to do a find, then yes.

---

<div class="post-metadata">

**Author:** ![markus](https://ziggit.dev/letter_avatar_proxy/v4/letter/m/b782af/32.png) [@markus](https://ziggit.dev/u/markus)\
**Post date:** [April 20, 2026, 9:06pm UTC](https://ziggit.dev/t/how-to-unroll-for-loop/15078/9 "2026-04-20T21:06:54Z")

</div>

Its a branchless iterative towers of hanoi solver haha

The most expensive operation is a single `% 3`
