# Julia seems an order of magnitude slower than Python when printing to the terminal, because of issue with "sleep"

**URL:** <https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151>\
**Category:** General Usage\
**Tags:** performance\
**Created:** [March 20, 2022, 4:17am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151 "2022-03-20T04:17:43Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 20, 2022, 4:17am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/1 "2022-03-20T04:17:43Z")

</div>

Hi all,

I’m running into couple of issues and a bottleneck when printing characters to the screen in Julia. This is because I was trying to add some new features to TerminalUserInterfaces.jl: [https://github.com/kdheepak/TerminalUserInterfaces.jl](https://github.com/kdheepak/TerminalUserInterfaces.jl)

I’m trying to recreate the following Python code in Julia:

```python
import os
import time

def main():
    delay = 1.0 / 1200
    while True:
        byte = os.read(0, 1)
        if not byte:
            break
        os.write(1, byte)
        time.sleep(delay)

if __name__ == " __main__":
    main()

```

This is code from a PyCon keynote talk by Brandon Rhodes: [Keynote by Brandon Rhodes - YouTube](https://youtu.be/rrMnmLyYjU8?t=1344)

The way the speaker runs this code is by using the following:

```julia
python animation.py < animation.txt

```

Here’s the `animation.txt` file if someone is interested in reproducing the animation:  
[https://gist.github.com/kdheepak/ff6b124a8511537f4266142c0a10bb52#file-animation-txt](https://gist.github.com/kdheepak/ff6b124a8511537f4266142c0a10bb52#file-animation-txt)

Firstly, I’m not able to write the code in Julia the way the speaker did. When I run `julia animation.jl < animation.txt`, it appears that `bytesavailable(stdin)` is never greater than zero (?). I’m not sure what I’m doing wrong here. I’ve even tried using some Stdlib functions but those error for some reason:

```julia
# import REPL
# term = REPL.Terminals.TTYTerminal("xterm", stdin, stdout, stderr)
# REPL.Terminals.raw!(term, true) # This line and the following line throws an error
# Base.start_reading(stdin)  

function main()
    delay = 1.0 / 1200
    while bytesavailable(stdin) > 0
        b = UInt8[0]
        readbytes!(stdin, b)
        write(stdout, b[1])
        sleep(delay)
    end
end

main()

```

The first few lines are based on this stack overflow answer:

[https://stackoverflow.com/a/60956065/5451769](https://stackoverflow.com/a/60956065/5451769)

These are the errors I get when I uncomment the first 3 lines or the 4th line:

```julia
ERROR: LoadError: MethodError: no method matching check_open(::IOStream)
Closest candidates are:
  check_open(::Union{Base.LibuvServer, Base.LibuvStream}) at ~/Applications/Julia-nightly.app/Contents/Resources/julia/share/julia/base/stream.jl:386
  check_open(::Base.Filesystem.File) at ~/Applications/Julia-nightly.app/Contents/Resources/julia/share/julia/base/filesystem.jl:114
Stacktrace:
 [1] raw!(t::REPL.Terminals.TTYTerminal, raw::Bool)
   @ REPL.Terminals ~/Applications/Julia-nightly.app/Contents/Resources/julia/share/julia/stdlib/v1.9/REPL/src/Terminals.jl:138
 [2] top-level scope

```

```julia
ERROR: LoadError: MethodError: no method matching start_reading(::IOStream)
Closest candidates are:
  start_reading(::Base.BufferStream) at ~/Applications/Julia-nightly.app/Contents/Resources/julia/share/julia/base/stream.jl:1541
  start_reading(::Base.LibuvStream) at ~/Applications/Julia-nightly.app/Contents/Resources/julia/share/julia/base/stream.jl:832
Stacktrace:
 [1] top-level scope

```

I’m able to get around this issue by writing the code this way:

```julia
function main()
    delay = 1.0 / 1200
    data = readavailable(stdin)
    for b in data
        write(stdout, b[1])
        sleep(delay)
    end
end

main()

```

This reads all the data from `stdin` at the beginning and then `write`’s out the `stdout`.

 ![Screen Shot 2022-03-19 at 10.03.09 PM](https://global.discourse-cdn.com/julialang/original/3X/7/9/793bb6cc31d18e537273dc515dee91be5bf513f6.png)

The thing is that Julia is several orders of magnitude slower than Python to print out to the terminal. Here’s the timing result when commenting out the `sleep` functions in both Python and Julia.

```julia
python animation.py < animation.txt 0.04s user 0.03s system 80% cpu 0.082 total
julia animation.jl < animation.txt 0.70s user 0.27s system 85% cpu 1.136 total

```

Python finishing in 0.04 seconds but Julia takes 0.70 seconds. This makes certain kinds of animations / widgets in the terminal untenable in Julia when I’m implementing them in `TerminalUserInterfaces.jl`.

I could be wrong about this, but I think this has to do with buffered vs unbuffered writes to stdout, and Julia defaulting to blocking and waiting for the `write` function to finish outputting text to the terminal.

I guess my question is how to get Julia to `print` and “return to execution” as fast as possible, i.e. without waiting for the character or byte to actually be written out to the terminal? I need to print something like this sequentially for `TerminalUserInterfaces.jl` so I don’t think using `async`, `Threads`, or multiprocessing would work. Any suggestions?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 20, 2022, 4:42pm UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/2 "2022-03-20T16:42:56Z")

</div>

I mean, if you run a script in this way you include:

- the startup time of Julia
- the time Julia needs to compile your code

On my computer the startup time is:

```julia
ufechner@tuxedi:~$ time julia -e ''

real	0m0,191s
user	0m0,139s
sys 0m0,084s

```

The compilation time is a bit more tricky to measure because of your I/O functions, but you could launch Julia like this:

```julia
julia --compile=min 

```

to find out if the compilation time is relevant at all.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [March 20, 2022, 6:56pm UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/3 "2022-03-20T18:56:01Z")

</div>

Some references: [JuliaLang/julia#36639](https://github.com/JuliaLang/julia/issues/36639), [JuliaLang/julia#43176](https://github.com/JuliaLang/julia/issues/43176), [Why is printint to a terminal slow (Discourse)](https://discourse.julialang.org/t/why-is-printing-to-a-terminal-slow/42987).

---

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 20, 2022, 9:54pm UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/4 "2022-03-20T21:54:50Z")

</div>

Thanks for the references. So apart from writing to a temporary IOBuffer, it appears that there’s no way around this? Maybe there’s a way I can use `ccall` to bypass Julia’s calls?

@ufechner7 this isn’t a precompilation issue btw. Even if I open a REPL and include the file, and call main multiple times, I get the same slow performance.

---

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 20, 2022, 10:09pm UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/5 "2022-03-20T22:09:12Z")

</div>

I’m surprised this doesn’t work when I run `julia animation.jl < animation.txt`:

```julia
function main()
    delay = 1.0 / 1200
    data = readavailable(stdin)
    for b in data
        @ccall write(0::Cint, UInt8[b[1]]::Ptr{UInt8}, 1::Cint)::Cint
        sleep(delay)
    end
end

main()

```

It just hangs with no output in the terminal. But this works in the REPL:

 ![Screen Shot 2022-03-20 at 4.08.03 PM](https://global.discourse-cdn.com/julialang/original/3X/f/c/fcad0a4f44356a48874e864d00e92b8c77e40952.png)

`A` is the character being printed and `1` is the return value.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 21, 2022, 5:12am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/6 "2022-03-21T05:12:29Z")

</div>

On my system [write (2)](https://man7.org/linux/man-pages/man2/write.2.html) has a different signature than the one you’re using. Also stdout has `fd=1`, I’m not sure how `fd=0` could ever work as that’s stdin?

The following works fine for me

```julia
function main()
    delay = 1.0 / 1200
    data = readavailable(stdin)
    for b in data
        @ccall write(1::Cint, UInt8[b[1]]::Ptr{Cvoid}, 1::Csize_t)::Cssize_t
        sleep(delay)
    end
end

main()

```

---

<div class="post-metadata">

**Author:** ![lawless-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lawless-m/32/30869_2.png) [@lawless-m](https://discourse.julialang.org/u/lawless-m)\
**Post date:** [March 21, 2022, 6:50am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/7 "2022-03-21T06:50:11Z")

</div>

btw. 0.04s vs 0.7s is not “several orders of magnitude”

it is 1 order of magnitude

“several” would be 70s or 700s or more

---

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 21, 2022, 7:34am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/8 "2022-03-21T07:34:17Z")

</div>

Thanks for the responses, that does appear to resolve my printing issue. I must have used `0` in the REPL but `1` in my script that I copy pasted here and typo’d while editing, or something like that.

> [@c42f](#):
>
> The following works fine for me

Does it display the animation for you? For me it just prints the characters to the terminal:

 ![Screen Shot 2022-03-21 at 1.32.18 AM](https://global.discourse-cdn.com/julialang/original/3X/6/4/6498bf836bbfc378e48bed441da5519effd02c3d.png)

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 21, 2022, 7:54am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/9 "2022-03-21T07:54:34Z")

</div>

> [@kdheepak](#):
>
> Does it display the animation for you?

Yes it works. But I needed to replace `e[` from the pasted file with the escape sequence `\e[`

---

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 21, 2022, 8:47am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/10 "2022-03-21T08:47:29Z")

</div>

Thanks! That runs. However, that is still slower than Python and I don’t understand why. I thought using `@ccall write` would bypass Julia’s `write` and the buffering issues.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 21, 2022, 8:51am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/11 "2022-03-21T08:51:29Z")

</div>

Since I always like a good deep dive into things, I’ve modified the code with 3 different versions and added some different timing code to see where the time is actually spent. I’m printing to `stderr` instead of `stdout` because it makes it easier to get the output of the timing code without some extra `redirect_std*` shenanigans.

The first version is just your `@ccall` version, the second version is the naive “just print to the stream one by one” version (except I reduced the redundant `b[1]` indexing - iterating over the byte array already gives you single bytes) and the third version is a `@ccall` version that doesn’t allocate a new `UInt8[]` each iteration.

> **Code**
>
> ```julia
> function main()
> delay = 1.0 / 1200
> data = readavailable(stdin)
> for b in data
> @ccall write(2::Cint, UInt8[b[1]]::Ptr{Cvoid}, 1::Csize_t)::Cssize_t
> #sleep(delay)
> end
> end
> 
> function main2()
> delay = 1.0 / 1200
> data = readavailable(stdin)
> for b in data
> write(stderr, b)
> #sleep(delay)
> end
> end
> 
> function main3()
> delay = 1.0 / 1200
> data = readavailable(stdin)
> slot = [0x0]
> for b in data
> slot[] = b
> @ccall write(2::Cint, slot::Ptr{Cvoid}, 1::Csize_t)::Cssize_t
> #sleep(delay)
> end
> end
> 
> ```

I invoke this file (`test.jl`) like the following:

```julia
time julia -L test.jl -e '@time main()' < animation.txt 2>/dev/null
time julia -L test.jl -e '@time main2()' < animation.txt 2>/dev/null
time julia -L test.jl -e '@time main3()' < animation.txt 2>/dev/null

```

This does nothing more than load the file into julia (`-L test.jl`) and runs a timing expression (`-e '@time main()'`). I redirect `stderr` to `/dev/null` to not mangle the output, but you can leave that out if you want to see it happen. I get these results:

```julia
$ time julia -L test.jl -e '@time main()' < animation.txt 2>/dev/null
  0.047315 seconds (76.72 k allocations: 3.360 MiB, 74.32% compilation time)

real	0m0.351s
user	0m0.356s
sys	0m0.277s
$ time julia -L test.jl -e '@time main2()' < animation.txt 2>/dev/null
  0.028545 seconds (56.13 k allocations: 2.104 MiB, 93.53% compilation time)

real	0m0.331s
user	0m0.364s
sys	0m0.242s
$ time julia -L test.jl -e '@time main3()' < animation.txt 2>/dev/null
  0.035286 seconds (56.12 k allocations: 2.088 MiB, 74.99% compilation time)

real	0m0.350s
user	0m0.406s
sys	0m0.226s

```

So it seems like we have our usual ~0.3s julia startup time, followed by about ~0.03s total execution time, of which ~75%-94% is compilation of the requested function, meaning about 0.0075s time spent reading from `stdin` and printing it back out.

EDIT:

This is on a somewhat recent commit of the repo:

```julia
julia> versioninfo()
Julia Version 1.9.0-DEV.171
Commit 842c27fad3 (2022-03-11 06:44 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: 4 × Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
  Threads: 4 on 4 virtual cores

```

This timing thing makes me want to have a “% allocations in compilation” blurb from `@time` though… As the code is right now, we’d have to compile the function ahead of time to figure out how much is allocated while running/reading from stdin directly (or modify the code to not read from stdin directly).

---

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 21, 2022, 9:00am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/12 "2022-03-21T09:00:21Z")

</div>

Thanks for looking into this @Sukera, I always enjoy your deep dives into the performance and benchmarking of code (especially from AoC).

~~The same code in Python runs faster than the numbers you shared, and I want to figure out how to make the Julia code run as fast~~ :

```julia
$ python animation.py < animation.txt 2> /dev/null  
0.04s user 0.03s system 79% cpu 0.084 total

```

I think like @fredrikekre posted, this has to do with buffered and unbuffered outputs / number of sys calls being made when `write` is being called.

Edit: I didn’t read your numbers correctly. I think when you run \>dev/null, it ends up being a lot faster? Maybe not printing to stdout doesn’t cause this issue.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 21, 2022, 9:01am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/13 "2022-03-21T09:01:17Z")

</div>

> [@kdheepak](#):
>
> I thought using `@ccall write` would bypass Julia’s `write` and the buffering issues.

Yes it certainly should bypass Julia’s IO layer. There will be some unwanted consequences from invoking `write()` directly — I think the task waiting on the `write()` will block but won’t yield correctly.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 21, 2022, 9:04am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/14 "2022-03-21T09:04:16Z")

</div>

It doesn’t have anything to do with buffering. The timings I’ve showed you above clearly show that the startup time of ~0.3s and the compilation time make up the difference and why it’s slower at all. If you take just the time spent for running the function that actually does the work (i.e., you time properly) you get 0.0075s, at worst on my machine.

> [@Sukera](#):
>
> ```julia
> 0.047315 seconds (76.72 k allocations: 3.360 MiB, 74.32% compilation time)
> 
> real	0m0.351s
> user	0m0.356s
> sys	0m0.277s
> 
> ```

Please note the extra output above - the `0.04` figure is the result of the `@time` call, timing the function itself. The difference between that and the `user` time is the julia startup time, which is independent of the code you run.

> [@c42f](#):
>
> Yes it certainly should bypass Julia’s IO layer. There will be some unwanted consequences from invoking `write()` directly — I think the task waiting on the `write()` will block but won’t yield correctly.

Yes it does, but the I/O layer is not _that_ slow here. It’s not a bottleneck.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 21, 2022, 9:08am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/15 "2022-03-21T09:08:28Z")

</div>

> [@kdheepak](#):
>
> Edit: I didn’t read your numbers correctly. I think when you run \>dev/null, it ends up being a lot faster? Maybe not printing to stdout doesn’t cause this issue.

No, that’s not an issue, at all. If I just print to `stdout` like you did I get only slightly slower timings, but still faster than python for printing itself:

```julia
$ time julia -L test.jl -e '@time main()' < animation.txt
[...] # animation output
  0.071099 seconds (76.72 k allocations: 3.360 MiB, 54.37% compilation time)

real	0m0.370s
user	0m0.395s
sys	0m0.257s

$ time julia -L test.jl -e '@time main2()' < animation.txt
[...] # animation output
  0.116960 seconds (102.97 k allocations: 3.230 MiB, 23.82% compilation time)

real	0m0.417s
user	0m0.431s
sys	0m0.265s

$ time julia -L test.jl -e '@time main3()' < animation.txt
[...] # animation output
  0.053860 seconds (56.12 k allocations: 2.088 MiB, 50.68% compilation time)

real	0m0.368s
user	0m0.374s
sys	0m0.274s

```

The biggest bottleneck is (as usual for these microbenchmarks of shell redirection) julia startup time, NOT execution/syscall time.

The only problem I can per se see is the spike in latency/allocations in `main2()`, i.e. the “julia native” version, which should already be tracked by this issue:

> <https://github.com/JuliaLang/julia/issues/39041>
>
> \`\`\`julia
> julia\> p, io = mktemp()
> ("/tmp/jl\_ry8Ly0", IOStream(\<fd 21\>))
> 
> juli…a\> @time write(io, 1234)
> 0.000006 seconds (1 allocation: 16 bytes)
> 8
> 
> julia\> versioninfo()
> Julia Version 1.5.3
> Commit 788b2c77c1 (2020-11-09 13:37 UTC)
> Platform Info:
> OS: Linux (x86\_64-linux-gnu)
> CPU: Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz
> WORD\_SIZE: 64
> LIBM: libopenlibm
> LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
> Environment:
> JULIA\_PKG\_SERVER =
> JULIA\_NUM\_THREADS = 4
> \`\`\`
> 
> Called in a tight loop, this quickly racks up allocations, overwhelming GC. This seems to be caused by the \`Int\` getting wrapped in a \`Ref\` further down the call chain, forcing it to be moved to the heap because of a \`@no\_inline\` even further down the call chain.
> 
> Feels like primitve types in \`write\` shouldn't allocate.

which is non-trivial to fix.

---

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 21, 2022, 9:11am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/16 "2022-03-21T09:11:43Z")

</div>

@Sukera

This is what I’m seeing:

[https://user-images.githubusercontent.com/1813121/159231792-3f111827-804c-47bd-a61c-94b14442b62e.mov](https://user-images.githubusercontent.com/1813121/159231792-3f111827-804c-47bd-a61c-94b14442b62e.mov)

The top right is Julia and the bottom right is Python. You can see that for me, Python proceeds through the animation waayy faster than Julia.

Are you saying that for you Julia is printing the animation faster than Python is printing the animation?

Is this an operating system / terminal issue maybe?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 21, 2022, 9:16am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/17 "2022-03-21T09:16:07Z")

</div>

> [@kdheepak](#):
>
> The top right is Julia and the bottom right is Python. You can see that for me, Python proceeds through the animation waayy faster than Julia.
> 
> Are you saying that for you Julia is printing the animation faster than Python is printing the animation?

No, that’s not what I’m saying. I’m saying that the _printing itself_ is not slower. It’s the 0.3s julia startup time that make up the difference, which is a long known & well improved problem.

> [@kdheepak](#):
>
> Is this an operating system / terminal issue maybe?

No, it isn’t. As I said above, it’s due to startup time, code loading & compilation. Python is extremely well optimized in that specific use case of terminal based scripting due to it being more than 20 years old by now and having been in use for terminal based scripting for A LOT of time by now. It’s also interpreted so there isn’t even any compilation going on.

---

<div class="post-metadata">

**Author:** ![kdheepak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdheepak/32/10881_2.png) [@kdheepak](https://discourse.julialang.org/u/kdheepak)\
**Post date:** [March 21, 2022, 9:21am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/18 "2022-03-21T09:21:23Z")

</div>

Wow, you are right. Julia is faster than Python for me too _when I remove the sleep_. But when I add the `sleep` function back in, Julia is slower. I guess my previous understanding was all wrong but I don’t understand why adding the same sleep in Julia and in Python would result in slower Julia code?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 21, 2022, 9:31am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/19 "2022-03-21T09:31:10Z")

</div>

> [@kdheepak](#):
>
> I guess my previous understanding was all wrong but I don’t understand why adding the same sleep in Julia and in Python would result in slower Julia code?

This is just a guess (meaning I haven’t tested it), but it’s very possible that the difference with `sleep` is due to regular `sleep` yielding to the julia task scheduler internally. My guess is that `time.sleep` in python doesn’t do/have anything similar to that. It’s also a little tricky to just swap in a `@ccall` version since the `sleep` function in C takes at least a second and `nanosleep` has a different API.

Another difference may be that julia’s `sleep` has a minimum sleep time of `0.001` seconds i.e. a millisecond - the python docs don’t say anything about a minimum sleep time for `time.sleep` (or I couldn’t find it). Your `1.0 / 1200 = 0.0008333...` is less than that, so it gets rounded up.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 21, 2022, 9:40am UTC](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151/20 "2022-03-21T09:40:27Z")

</div>

> [@Sukera](#):
>
> Yes it does, but the I/O layer is not _that_ slow here. It’s not a bottleneck.

Yeah, I’m just pointing out that there’s some subtle and problematic downsides to bypassing Julia’s IO layer. This isn’t a problem for small test scripts. But it could be quite a problem for a larger piece of code if there’s other tasks going on concurrently.

[Next page](https://discourse.julialang.org/t/julia-seems-an-order-of-magnitude-slower-than-python-when-printing-to-the-terminal-because-of-issue-with-sleep/78151.md?page=2)
