← Latest papers
💻 computer science

The Warmup Protocol Problem: JIT, GC, and Lazy Evaluation Effects on WRSS in Julia, Haskell, and Python

This study investigates how warmup protocol choices—specifically the exclusion or inclusion of JIT compilation, garbage collection, and deferred evaluation effects—distort the Workload–Runtime Scaling Signature (WRSS) and Bottleneck Transition Points in Julia, Haskell, and Python, revealing that standard steady-state benchmarks may misrepresent real-world first-execution performance and produce misleading cross-language scaling conclusions.

Original authors: Albert Schulle

Published 2026-10-06
📖 4 min read☕ Coffee break read

Original authors: Albert Schulle

Original paper licensed under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). ✨ This is an AI-generated explanation of the paper below. It is not written or endorsed by the authors. For technical accuracy, refer to the original paper. Read full disclaimer

When computer scientists try to measure how fast a program runs, they face a hidden trap. Modern software does not start at full speed the moment a user clicks a button. Instead, the computer often spends its first moments preparing the program, translating code into a form the machine understands, or clearing out old data to make room for new tasks. This preparation phase is known as "warmup." For decades, researchers studying how computers handle multiple tasks at once have tried to ignore this warmup, measuring only the steady, smooth running that happens afterward. They believed this gave the purest view of a language's true power. But this approach assumes that programs always run for a long time on the same data, a condition that rarely exists in the real world where software often starts fresh or changes its workload frequently.

A recent study challenges this long-held assumption by asking what happens when we stop hiding the warmup. The researchers focused on three popular programming languages: Julia, Haskell, and Python. They used a specific method called the Workload–Runtime Scaling Signature to break down the time a program takes into three parts: the time workers spend doing actual calculations, the time spent combining their results, and the leftover time spent on overhead like memory management or translation. By running the same three complex tasks—sorting a massive list of numbers, finding the closest pair of points in a field, and summing a huge set of values—they compared two very different ways of measuring performance. One way followed the traditional rule of warming up the computer first, while the other measured the program from the very cold start, including all the initial delays.

The results revealed that the choice of how to measure matters more than many realized. When the researchers included the cold start, the picture of how well these languages scale changed dramatically. For the Julia language, which uses a system that translates code while it runs, the initial translation time was so heavy that it completely altered the results. In the traditional warmup tests, Julia appeared to handle large numbers of workers efficiently until a certain point, after which the time spent combining results became the bottleneck. However, when the initial translation was included in the clock, that bottleneck appeared much earlier. The program seemed to hit a wall with far fewer workers than the warmup tests suggested, because the time spent translating code inflated the "leftover" time, making the system look less efficient than it actually is once it is running smoothly.

Haskell behaved differently. Because this language delays calculations until they are absolutely needed, the initial costs were spread out over the entire run rather than happening all at once at the beginning. This meant that whether the researchers warmed up the system first or measured it from a cold start, the results looked almost the same. The language's design naturally smoothed out the rough edges of starting up, making it surprisingly stable regardless of how the test was conducted. Python fell somewhere in the middle. Its performance depended heavily on how the data was moved between different parts of the computer. When the task required moving large amounts of data through a slow, serialized process, the cold start added significant delays that shifted the results. But when the data could be shared more directly, the effect was smaller.

Perhaps the most important finding was that the type of task being performed changed how much the warmup mattered. For a task that was purely about crunching numbers, the initial delays were so small compared to the total work that they barely changed the outcome. But for tasks that involved a lot of organizing and combining data, the initial delays became a major part of the total time. In these cases, ignoring the warmup led to a false sense of security about how well the software would perform in a real-world scenario where it might be started and stopped frequently. The study concludes that the standard way of measuring parallel performance, which strips away the startup phase, tells a story that is accurate for steady, long-running jobs but misleading for the dynamic, short-lived tasks that dominate modern computing. To truly understand how these languages behave, researchers and developers must report exactly how they handled the startup, acknowledging that the first few seconds of a program's life can define its entire performance signature.

Drowning in papers in your field?

Get daily digests of the most novel papers matching your research keywords — with technical summaries, in your language.

Try Digest →