Commit Graph
12432 Commits
Author SHA1 Message Date
Peter Ullrich 11f7d8f84a Refactor Float.round/2 algorithm for better performance (#15329)
The previous implementation noted the trade-off:

```elixir
# This implementation is slow since it relies on big integers.
# Faster implementations are available on more recent papers
# and could be implemented in the future.
```

It computed `m * power_of_5(count)` where `count` could grow to ~104, producing 250-bit bignums for a single division. The cost grew with both float magnitude and target precision.

### Benchmark results

11 different float workloads, measured with Benchee on Apple M2. Reported times are the median μs of one iteration over all 11 workloads.

precision | current | cox (this PR) | native_double | cox vs current | native_double vs current | native_double vs cox |
|---|---|---|---|---|---|---|
| 0 | 0.25 μs | 0.25 μs | 0.25 μs | 1.1× | 1.1× | ~tied |
| 1 | 2.42 μs | 0.33 μs | 0.33 μs | **7.1×** | 7.0× | ~tied |
| 2 | 2.67 μs | 0.63 μs | 0.33 μs | **3.8×** | 7.7× | 2.0× |
| 3 | 4.29 μs | 0.63 μs | 0.33 μs | **5.8×** | 11.9× | 2.1× |
| 5 | 5.50 μs | 0.67 μs | 0.33 μs | **6.8×** | 15.6× | 2.3× |
| 8 | 7.21 μs | 0.96 μs | 0.38 μs | **7.5×** | 19.5× | 2.6× |
| 12 | 7.75 μs | 0.96 μs | 0.38 μs | **8.2×** | 20.3× | 2.5× |
| 15 | 8.58 μs | 1.58 μs | 0.38 μs | **5.3×** | 22.8× | 4.3× |

Median μs per iteration over the 11-float mixed workload (per-call median ≈ value / 11).

- **`current`** is the bignum-based implementation we're replacing
- **`cox`** is this PR
- **`native_double`** is included as a "what does this look like in pure native float arithmetic" reference (`:erlang.round(f * pow) / pow`) - it's 2-4× faster than Cox but incorrect on tie inputs because `5.5675 * 1000` rounds to `5567.5` in IEEE due to double-rounding (multiplication round + integer round), then bumps to `5568`. It's why we can't simply use the obvious approach. Cox preserves exact semantics by working on the float's true binary representation.

#### Floats benchmarked

```
floats = [
  {"small_pi",       3.141592653589793},   # typical small value
  {"common_money",   5.5675},               # tie-boundary case
  {"large_e10",      1.2345e10},            # large magnitude
  {"tiny_e_neg8",    1.2345e-8},            # very small magnitude
  {"near_zero",      0.00001},              # close to zero
  {"negative",       -123.456789},          # negative sign
  {"integer_valued", 12.0},                 # exactly representable integer
  {"tie_half",       12.5},                 # half-tie
  {"tie_5675",       5.5675},               # documented tie example
  {"large_e30",      1.234e30},             # very large
  {"max_finite_ish", 1.7e308}               # near max double
]
```
2026-05-01 12:59:07 +02:00
Łukasz Samson f4e1b34617 Fix incorrect guard type refinement with length/map_size and != operator (#15327)
Previously `empty_list()` and `empty_map` were returned for `length(x) != n` and `map_size(x) != n` when n > 0. Now the types are widened to `list()` and `open_map()`
2026-04-30 18:30:07 +02:00
José Valim 55a3899e75 Add more tests around precision 2026-04-29 22:10:46 +02:00
Łukasz Samson ada2817d72 Fix invalid type inference on size compare in guards (#15324) 2026-04-29 22:06:23 +02:00
Guillaume Duboc 89e0106afc Fix map union optimization for open maps (#15322) 2026-04-29 08:48:16 +02:00
Łukasz Samson e39a1ca796 Consistently return path as binary in relative_to_cwd (#15316)
Previously if path parameter was passed in as chardata it was returned as is on `:file.get_cwd` failure
All `relative_to` and `join` code paths normalize to binary
2026-04-28 22:51:09 +02:00
Łukasz Samson 007efde2d5 Fix reentrancy of Code.eval_* (#15306)
Keep env and dbg callbacks on stacks in process dict

Closes #15303
2026-04-28 19:38:28 +02:00
Guillaume Duboc eb8bbc9c29 Fix map difference union optimization (#15319) 2026-04-28 19:12:34 +02:00
José Valim c5332235ab Perform all side-effect in order in in/2 2026-04-27 12:25:49 +02:00
José Valim e5d8b00e5b Remove maps:put/3 inlining, as it is done by the Erlang compiler, closes #15313 2026-04-27 12:03:24 +02:00
José Valim 2ba06cc40b Make preserving dir permissions opt-in, closes #15308 (#15312) 2026-04-26 19:08:23 +02:00
José Valim 68aae43703 Revert "Add each_directory to File.rm_rf, closes #15308 (#15311)"
This reverts commit d02e61d75e.

It did not address the original root problem.
2026-04-26 18:02:46 +02:00
Rafał Studnicki 2019de2d82 Switch {:duplicate, :key} key_ets to ordered_set with composite keys (#15304)
Switch {:duplicate, :key} key_ets to ordered_set

Change init_key_ets to create an ordered_set table for {:duplicate, :key}
and add ordered boolean to Partition state.
2026-04-26 11:12:04 +02:00
José Valim d02e61d75e Add each_directory to File.rm_rf, closes #15308 (#15311) 2026-04-26 10:39:46 +02:00
Łukasz Samson 76d3fbad88 Disallow raw CR line ending in strings, comments and after ? (#15307) 2026-04-26 09:32:12 +02:00
José Valim 870d28fe64 Fix regression where we inferred the wrong type in a case branch that raises 2026-04-25 16:55:40 +02:00
José Valim 2d6e61c4f5 Compute negated types from precise none() branches 2026-04-22 22:11:26 +02:00
Łukasz Samson 99e0fe50a3 Fix Macro.Env.define_require/4 spec (#15302)
It may error when called with invalid `as` option
2026-04-22 15:34:15 +02:00
Łukasz Samson 8a4915008d Fix Macro.expand_literals/3 spec (#15301) 2026-04-22 15:32:40 +02:00
José Valim 0fe5b13320 Perform reverse arrows on with even when not precise 2026-04-22 12:18:03 +02:00
José Valim 808075d87a Implement reverse arrows for with 2026-04-21 20:17:08 +02:00
Łukasz Samson 5e7190c39f Fix static_atoms_encoder docs and spec (#15294)
Fixes #15293
2026-04-21 13:42:33 +02:00
Łukasz Samson 4ad7497d0e Consistently validate column option passed to parser (#15295)
Apply the same guard `line` option uses
2026-04-21 13:41:04 +02:00
Dinesh Anbazhagan 25cbbfe5d2 Fix errors in getting-started and mix-and-otp guides (#15289) 2026-04-20 20:34:28 +02:00
José Valim 890d9bbf00 Type checking improvements
* Ensure we do not accumulate previous information across clauses
* Avoid union(a, not a) when building domains
* Ensure union with an open map/tuples returns the open map/tuple
* Remove deep traversal on bdd leaf intersection which was slowing
  compilation of projects like open_api_spex

Closes #15285.
2026-04-18 18:13:48 +02:00
José Valim 20fef8cd1c Change directory permissions after writing, closes #15286 2026-04-18 09:11:57 +02:00
Guillaume Duboc 9231515db8 Bdd negation and difference optimizations (#15287) 2026-04-17 17:24:44 +02:00
José Valim d5e032efd1 Increase inspect limit to help print deeply nested data structures 2026-04-17 08:50:19 +02:00
Łukasz Samson 5e44c78fff Fix compiler crash on invalid nested bitstring (#15280) 2026-04-16 15:32:48 +02:00
Lukasz Samson 4d56bdd898 Do not reset quote level on calls in has_unquotes/2
The bug was introduced in 146fb4e3ff

Signed-off-by: José Valim <jose.valim@gmail.com>
2026-04-16 13:49:37 +02:00
José Valim 2e9981d98c Raise when splicing cons without head, closes #15282 2026-04-16 13:48:08 +02:00
Wojtek Mach ed478e816b Don't crash when inspecting OTP 29 native records (#15278) 2026-04-16 13:32:57 +02:00
José Valim 370e7db14a Ensure compiler modules are returned on failures, closes #15279 2026-04-16 08:26:16 +02:00
José Valim d67cb9634b Add performance regression test for open and closed maps 2026-04-15 21:07:24 +02:00
José Valim a37db60f78 Move :open check inside leaf_bdd_intersection 2026-04-15 19:38:04 +02:00
José Valim 116f8f472f Also optimize bottoms in leaf bdd intersections 2026-04-15 17:11:56 +02:00
José Valim 9c1bd76b26 Remove expected intersection as now track underscores 2026-04-15 17:11:56 +02:00
José Valim 8ba8ad709f Document halt responsibilities for resources
Closes #15265.
Closes #15266.
2026-04-15 09:09:58 +02:00
José Valim 37dc125f2a Check both expand and dispatch are not in stacktrace 2026-04-15 09:01:42 +02:00
José Valim 9fb8fb1216 Add comments justifying use of subtyping, closes #15273 2026-04-15 08:59:22 +02:00
Łukasz Samson 5a1fa351dc Fix invalid module reference in prune_stacktrace (#15272)
Closes #15271
2026-04-15 08:59:08 +02:00
Jean Klingler 20cd669a0d Optimize Keyword.validate/2 to avoid building new list (#15269) 2026-04-15 07:06:59 +09:00
José ValimandGuillaume Duboc 03b45e521d Remove redundant line empty when we eliminate negations (#15196)
Co-authored-by: Guillaume Duboc <guilduboc@gmail.com>
2026-04-13 21:41:32 +02:00
José Valim bcfefa18ed Simplify Enum.dedup for lists 2026-04-13 21:37:57 +02:00
Łukasz Samson b7a832ea32 Add missing catch-all in :elixir_import.is_sigil/1 (#15264)
Fixes a compiler crash when importing a module with
only: :sigils option when the imported module exports
non sigil symbols with `sigil_` prefix.

Closes #15263.
2026-04-13 20:25:33 +02:00
José Valim 8011552eac Remove ?break handling duplication 2026-04-13 19:42:28 +02:00
José Valim ebb7c73353 Improve inference across for and try 2026-04-13 19:31:08 +02:00
Łukasz Samson 898f1a2f69 Reject unsupported newlines in tokenizer ASCII fast path (#15262) 2026-04-13 19:30:31 +02:00
José Valim 603602e67b Implement reverse arrows for case (#15260) 2026-04-13 15:21:08 +02:00
José Valim 245066b405 Relax handling of __exception__
We were used to assert it to be true but,
given the value is not used in any shape,
we can relax the definition and simply assert
on the presence of the key.

Closes #15251.
2026-04-11 17:42:01 +02:00