Pangram verdict · v3.3
We believe that this text is a mix of AI and human-written content.
AI likelihood · overall
MixedArticle text · 1,253 words · 2 segments analyzed
Julia version 1.13 has been released. We want to thank all the contributors to this release and all the testers who helped find regressions and issues in the pre-releases. Without you, this release would not have been possible. The full list of changes can be found in the NEWS file, but here we'll give a more in-depth overview of some of the release highlights. Latency (TTFX) improvementsREPL improvementsSyntax highlightingNew fzf-style history searchBracketed paste on Windows@__FUNCTION__Hashing changesFaster GC by skipping image objects during markingScheduler and interrupt fixesIntrospection with type annotationsTracing top-level evaluation with --trace-evalJuliaC/trimPkgChange in default compression algorithm from gzip to zstdPerformance improvementsRegistries for packages tracked in the manifestRecursively collect sourcespkg> add now tries to add the same version as already-loaded packagesPkg.test no longer defaults to enabling strict bounds checkingJuliaup GUI Latency (TTFX) improvements Ian Butterworth, many others Julia 1.13 takes roughly 30% less time to precompile packages than 1.12, and roughly 10-20% less time than 1.10 (LTS) depending on the machine. Time To First X (TTFX), the time from starting Julia to getting a first result, is made up of three main costs: precompiling packages, loading them, and running the code. With the help of the community-submitted workflows at Julia-TTFX-Snippets, we have started measuring these costs more systematically on real-world examples and optimizing Julia against them. The chart below shows the geometric mean across all 39 currently submitted workflows, on two machines. Precompilation is the fastest of 2 runs; load and execution times are the fastest of 3 runs. This monitoring is now also part of Julia's own development process: new TTFX CI jobs run on relevant pull requests and on every commit to master, and the results are tracked at perf.julialang.org/ttfx. That tracking went live on September 7, 2026; measurements before then were ad hoc. Julia 1.13 startup is also ~20% faster than 1.12. % hyperfine --warmup 3 --runs 20 -N \ --command-name "julia 1.12" "julia +1.12 --startup-file=no -e ''" \ --command-name "julia 1.13" "julia +1.13 --startup-file=no -e ''" Benchmark 1: julia 1.12 Time (mean ± σ): 69.1 ms ± 1.0 ms [User: 50.1 ms, System: 18.1 ms] Range (min … max): 68.0 ms … 72.6 ms 20 runs Benchmark 2: julia 1.13 Time (mean ± σ): 56.7 ms ± 0.5 ms [User: 49.1 ms, System: 18.9 ms] Range (min … max): 56.0 ms … 58.1 ms 20 runs Summary julia 1.13 ran 1.22 ± 0.02 times faster than julia 1.12 REPL improvements Syntax highlighting Timothy, Kristoffer Carlsson The Julia REPL now has syntax highlighting (without having to load an external package like OhMyREPL.jl): By default, the color scheme is quite conservative, but it is easy to customize (see the documentation for the REPL). As an example, here is the same code but using the Monokai color scheme: New fzf-style history search Timothy The history search (entered by default via Ctrl-R) has been redesigned and now works similarly to the command-line fuzzy finder fzf: Among other things, the new history search has support for: Fuzzy searching in the history. Showing what REPL mode was used for the command. Selecting multiple search results to put into the prompt buffer. Syntax highlighting of the code, matching the REPL itself. Enter the history search and type ? to see the full help. Bracketed paste on Windows Bracketed paste allows an application running in a terminal to know when text is being pasted (as opposed to just being typed). This can allow for more efficient and correct processing of the text being pasted. This functionality has been enabled on Linux and macOS for a long time but is now also finally available on Windows. As a concrete example, the videos below show the behavior of pasting a ~500-line function into the Julia REPL before and after enabling bracketed paste on Windows. Before: After: @__FUNCTION__ Miles Cranmer, Jeff Bezanson Like the existing @__MODULE__ and @__FILE__ macros, the new @__FUNCTION__ macro references the innermost containing function even if that function is anonymous. This should work in all kinds of functions, and is public API, unlike the internal variable #self#. julia> fact = n -> n <= 1 ? 1 : n * @__FUNCTION__()(n - 1); julia> fact(5) 120 Hashing changes Andy Dienes, Jameson Nash The hash function has been replaced. The byte-hashing algorithm is now RapidhashNano. This hash is used by default for AbstractString and many numeric types like BigInt, Rational, and large Real or Integer values. It is also much easier now for custom types to opt in to the generic implementations without having to first convert to a supported type (like String). This change offers several advantages compared to the pre-existing implementation based on MurmurHash3. It has significantly better performance, is a streaming hash so it no longer requires the length of the input up front, and has moved from C to pure Julia for better readability and maintainability. To demonstrate the performance improvement on long strings: using BenchmarkTools, Downloads io = IOBuffer() Downloads.download("https://www.gutenberg.org/cache/epub/1080/pg1080.txt", io) s = String(take!(io)); # 1.12 @btime hash($s) 8.555 μs (0 allocations: 0 bytes) 0x5fbd2717019846ea # 1.13 @btime hash($s) 1.742 μs (0 allocations: 0 bytes) 0x718308e795047519 And a demonstration of opting in to a faster fallback: struct MyString <: AbstractString s::String end m = MyString(s); # 1.12 Base.iterate(m::MyString) = iterate(m.s) Base.iterate(m::MyString, i::Integer) = iterate(m.s, i) @btime hash($m) 204.583 μs (21 allocations: 107.02 KiB) 0x5fbd2717019846ea # 1.13 Base.codeunit(m::MyString) = codeunit(m.s) Base.codeunits(m::MyString) = codeunits(m.s) @btime hash($m) 1.750 μs (0 allocations: 0 bytes) 0x718308e795047519 The hash for small fixed-width data has also changed. The final mixing step is now a single-round XMX construction with some carefully tuned constants, and the mixing step now properly avalanches when composing hash calls; previously the mixing step always simplified to a linear function at every composition depth. This change to the mixing step does introduce a data dependency (and thus potentially lower performance) when sequentially hashing elements together in a tight loop, e.g. foldr(hash, collection), but the algorithm for hashing AbstractArray has been partially unrolled at small to medium sizes, maintaining several hash accumulators in parallel, and will be much faster at most lengths. Some important reminders: hash remains noncryptographic. Also, the default seed has changed. Custom hash methods should always accept the seed as an argument like hash(x::MyType, h::UInt) and never provide a default value like hash(x::MyType, h::UInt=0), since the correct seed is determined by the caller. Faster GC by skipping image objects during marking Cody Tapscott Every Julia session starts with a large number of objects that were loaded from the system image, and every package that gets loaded brings its own package image with even more of them: method tables, type information, compiled code, constants and so on.
These objects are never freed, and they are rarely mutated, yet until now a full garbage collection would walk through all of them to mark them as reachable, just like any other object on the heap. For a session with a handful of large packages loaded, this could easily be the dominant cost of a full collection. In Julia 1.13, objects in the sysimage and in package images are loaded as permanently marked and the mark phase never enters them. The few mutations that do happen to image objects (for example, when a method is added to an existing function) are tracked separately so that any new objects they point to are still kept alive. The effect is that the cost of a full collection now scales with the size of the heap that your program actually created, not with the amount of code that has been loaded.