Why is odin so slow to build "hello world" project in wsl?

package main

import "core:fmt"

main :: proc() {
	fmt.println("hello world")
}

$ odin build main.odin -file -show-timings

Total Time                         -  2048.954 ms - 100.00%
initialization                     -    15.350 ms -   0.74%
parse files                        -    44.911 ms -   2.19%
type check                         -  1372.591 ms -  66.98%
LLVM API Code Gen (   57 modules ) -   519.315 ms -  25.34%
lld-link                           -    96.778 ms -   4.72%

package main

import "base:runtime"

main :: proc() {
	runtime.print_string("hello world")
}

$ odin build main.odin -file -show-timings

Total Time                         -   345.409 ms - 100.00%
initialization                     -    11.351 ms -   3.28%
parse files                        -    20.846 ms -   6.03%
type check                         -   133.405 ms -  38.62%
LLVM API Code Gen (   30 modules ) -    93.734 ms -  27.13%
lld-link                           -    86.064 ms -  24.91%

Did you try running it again? Because that sounds like you hit something off with your CPU.

I mainly use WSL. I just installed Odin on Windows to compare and realized that odin build in WSL is 5x~10x slower!?

wsl sysinfo:

OS: Fedora Linux 44 (WSL) x86_64
Host: Windows Subsystem for Linux - Fedora-44 (2.7.12.0)
Kernel: Linux 7.1.5-locietta-WSL2-xanmod1
Shell: fish 4.6.0
CPU: AMD Ryzen 5 4600H (12) @ 2.99 GHz

odin version dev-2026-09

windows:

$ ./odin.exe build hello.odin -file -show-timings
Total Time                         -   288.466 ms - 100.00%
initialization                     -     8.847 ms -   3.06%
parse files                        -    21.071 ms -   7.30%
type check                         -   109.579 ms -  37.98%
LLVM API Code Gen (   57 modules ) -    84.804 ms -  29.39%
msvc-link                          -    64.160 ms -  22.24%

I built odin from source using make release-native, the compilation speed was a bit faster, but still much slower than odin on Windows.

$ ./odin build hello.odin -file -show-timings
Total Time                         -  1605.219 ms - 100.00%
initialization                     -     4.231 ms -   0.26%
parse files                        -    40.075 ms -   2.49%
type check                         -  1342.989 ms -  83.66%
LLVM API Code Gen (   57 modules ) -   127.220 ms -   7.92%
ld-link                            -    90.695 ms -   5.65%

pre-built odin on wsl:

update dependency tree for procedures - 1216.465 ms - 59.83%

$ ./odin build hello.odin -file -show-more-timings
Total Time                                                                      -  2033.127 ms - 100.00%
initialization                                                                  -     2.409 ms -   0.11%
init thread pool                                                                -     1.486 ms -   0.07%
init universal                                                                  -     8.603 ms -   0.42%
init asm tables                                                                 -     0.298 ms -   0.01%
parse files                                                                     -    36.158 ms -   1.77%
init checker info                                                               -     0.000 ms -   0.00%
checker info: general                                                           -     0.039 ms -   0.00%
init proc queues                                                                -     8.486 ms -   0.41%
type check                                                                      -     0.000 ms -   0.00%
map full filepaths to scope                                                     -     0.704 ms -   0.03%
init worker data                                                                -     0.014 ms -   0.00%
create file scopes                                                              -     1.334 ms -   0.06%
collect entities                                                                -     2.598 ms -   0.12%
export entities - pre                                                           -     4.254 ms -   0.20%
check_import_entities - sort packages                                           -     0.006 ms -   0.00%
check_import_entities - collect file decls                                      -     5.235 ms -   0.25%
check_import_entities - check delayed entities                                  -     3.526 ms -   0.17%
export entities - post                                                          -     0.581 ms -   0.02%
add entities from packages                                                      -     1.136 ms -   0.05%
check all global entities                                                       -    34.096 ms -   1.67%
init preload                                                                    -     0.016 ms -   0.00%
add global untyped expression to queue                                          -     0.051 ms -   0.00%
check procedure bodies                                                          -    23.558 ms -   1.15%
check foreign import fullpaths                                                  -     0.109 ms -   0.00%
add entities from procedure bodies                                              -     1.262 ms -   0.06%
check all scope usages                                                          -    34.694 ms -   1.70%
add basic type information                                                      -     0.061 ms -   0.00%
check for type cycles                                                           -     0.671 ms -   0.03%
check for inline cycles                                                         -     0.554 ms -   0.02%
check deferred procedures                                                       -     0.017 ms -   0.00%
check objc context provider procedures                                          -         0 ms -      0%
calculate global init order                                                     -     0.000 ms -   0.00%
calculate_global_init_order: generate entity dependency graph                   -     2.383 ms -   0.11%
generate_entity_dependency_graph: Calculate edges for graph M - Part 1          -     3.741 ms -   0.18%
generate_entity_dependency_graph: Calculate edges for graph M - Part 2a (init)  -     0.000 ms -   0.00%
generate_entity_dependency_graph: Calculate edges for graph M - Part 2b (procs) -     1.198 ms -   0.05%
generate_entity_dependency_graph: Calculate edges for graph M - Part 2c (vars)  -     0.017 ms -   0.00%
generate_entity_dependency_graph: Dependency Count Checker                      -     0.073 ms -   0.00%
calculate_global_init_order: priority queue create                              -     0.028 ms -   0.00%
calculate_global_init_order: queue sort                                         -     0.383 ms -   0.01%
add type info for type definitions                                              -     0.393 ms -   0.01%
update dependency tree for procedures                                           -  1216.465 ms -  59.83%
generate minimum dependency set                                                 -     4.120 ms -   0.20%
check bodies have all been checked                                              -     0.092 ms -   0.00%
check #soa types                                                                -     0.000 ms -   0.00%
update minimum dependency set again                                             -     3.101 ms -   0.15%
check test procedures                                                           -     0.001 ms -   0.00%
check entry point                                                               -     0.030 ms -   0.00%
check unchecked (safety measure)                                                -     0.568 ms -   0.02%
check unique package names                                                      -     0.054 ms -   0.00%
sanity checks                                                                   -     0.000 ms -   0.00%
check instrumentation calls                                                     -     0.000 ms -   0.00%
add untyped expression values                                                   -     1.156 ms -   0.05%
initialize and check for collisions in type info array                          -     0.062 ms -   0.00%
sort init and fini procedures                                                   -     0.002 ms -   0.00%
check intrinsics.__entry_point usage                                            -     0.000 ms -   0.00%
collate type info stuff                                                         -     0.000 ms -   0.00%
type check finish                                                               -    18.980 ms -   0.93%
LLVM API Code Gen (   57 modules )                                              -     0.000 ms -   0.00%
LLVM Initializtion                                                              -     0.211 ms -   0.01%
LLVM Create Target Machine                                                      -     2.836 ms -   0.13%
LLVM Global Variables                                                           -     0.717 ms -   0.03%
LLVM Runtime Objective-C Names Creation                                         -     0.000 ms -   0.00%
LLVM Runtime Startup Creation (Global Variables & @(init))                      -     1.881 ms -   0.09%
LLVM Runtime Cleanup Creation & @(fini)                                         -     0.135 ms -   0.00%
LLVM Global Procedures and Types                                                -     8.288 ms -   0.40%
LLVM Procedure Generation                                                       -   115.504 ms -   5.68%
LLVM Procedure Generation (missing)                                             -     8.399 ms -   0.41%
LLVM Add Foreign Library Paths                                                  -     0.002 ms -   0.00%
LLVM Function Pass                                                              -     7.713 ms -   0.37%
LLVM Remove Unused Functions and Globals                                        -     0.132 ms -   0.00%
LLVM Module Pass and Verification                                               -   132.512 ms -   6.51%
LLVM Correct Entity Linkage                                                     -     0.028 ms -   0.00%
LLVM Object Generation (37 used modules)                                        -   234.513 ms -  11.53%
ld-link                                                                         -    95.068 ms -   4.67%
remove temp files                                                               -     0.340 ms -   0.01%
$ ./odin build hello.odin -file -show-timings
Total Time                         -  1393.338 ms - 100.00%
initialization                     -    16.711 ms -   1.19%
parse files                        -    49.877 ms -   3.57%
type check                         -   514.530 ms -  36.92%
LLVM API Code Gen (   57 modules ) -   513.299 ms -  36.83%
ld-link                            -   298.916 ms -  21.45%

$ ./odin build hello.odin -file -show-timings
Total Time                         -   913.421 ms - 100.00%
initialization                     -    13.405 ms -   1.46%
parse files                        -    47.861 ms -   5.23%
type check                         -   244.842 ms -  26.80%
LLVM API Code Gen (   57 modules ) -   516.852 ms -  56.58%
ld-link                            -    90.456 ms -   9.90%

$ ./odin build hello.odin -file -show-timings
Total Time                         -  2081.477 ms - 100.00%
initialization                     -    13.928 ms -   0.66%
parse files                        -    47.280 ms -   2.27%
type check                         -  1408.194 ms -  67.65%
LLVM API Code Gen (   57 modules ) -   518.246 ms -  24.89%
ld-link                            -    93.822 ms -   4.50%

$ ./odin build hello.odin -file -show-timings
Total Time                         -  2050.497 ms - 100.00%
initialization                     -    13.241 ms -   0.64%
parse files                        -    45.436 ms -   2.21%
type check                         -  1398.412 ms -  68.19%
LLVM API Code Gen (   57 modules ) -   492.602 ms -  24.02%
ld-link                            -   100.799 ms -   4.91%

$ ./odin build hello.odin -file -show-timings
Total Time                         -  1777.780 ms - 100.00%
initialization                     -    13.646 ms -   0.76%
parse files                        -    91.023 ms -   5.12%
type check                         -   855.285 ms -  48.10%
LLVM API Code Gen (   57 modules ) -   521.783 ms -  29.35%
ld-link                            -   296.036 ms -  16.65%

I had AI optimize the Odin compiler for WSL, and the compilation speed is much faster now, but it’s still about 200ms slower than Odin on Windows.

$ ./odin build hello.odin -file -show-timings
Total Time                         -   435.413 ms - 100.00%
initialization                     -    13.152 ms -   3.02%
parse files                        -    72.950 ms -  16.75%
type check                         -   102.763 ms -  23.60%
LLVM API Code Gen (   57 modules ) -   161.881 ms -  37.17%
ld-link                            -    84.650 ms -  19.44%

WSL will always be slower than native Windows because of how WSL works. It’s inherent to how WSL works.

But if you had AI optimize the compiler, what exactly did it do?

1 Like

I didn’t know about -thread-count before, now I just need to build odin from source using make release-native, and use -thread-count:4, which is faster and more stable than the AI-modified version.

1 Like

You need to choose the appropriate number of threads based on the project size. On my machine’s WSL, 4 threads perform best for small projects, 6 threads for medium projects like ols and odinfmt, and 8 threads for large projects like odin-1-million-lines-of-code-bench.

Using -linker:mold provides some speedup at higher thread counts, but the LLVM codegen is too slow, so the improvement is barely noticeable.

More information about this issue in WSL is here: WSL2: futex thrashing causes very slow compile time on hello world (simple workaround) · Issue #7128 · odin-lang/Odin