The patch computes byte lookups based on the prefix. For example,
Á, É, etc all have the same prefix <<195>>, so they are lumped
together for lookup and then we just do a byte lookup later. We
tried doing the byte lookup on 64-element tuple (since the byte
is always within 0b10000000 and 0b10111111) but that's slower,
especially because we need to check the byte range for invalid
Unicode, so instead the last byte lookup is a case. Grouping the
top-level lookup makes the cost of a miss 3x cheaper albeit a
hit is 10% more expensive and reduces bytecode size.
- Remove mention of handling charlist (which it does not).
- Also mention in the docs of `Module.concat/1` / `Module.concat/2` that
this handles both binaries and atoms.
In order to support calendars which can change
era any time during the calendar year, the callback
Calendar.year_of_era/1 is changed to Calendar.year_of_era/3.
Since Calendar.ISO.year_of_era/1 is a public function,
default arguments for month and day are set if
year_of_era/1 is called to allow compatibility with
any existing code that relies upon this function.
Task.Supervisor.async/* would copy the MFA to the supervisor
process. async_stream/* would additionally copy the value to
the stream coordinator. This commit makes it so those copies
are no longer necessary. The only unnecessary copy is in
Task.Supervisor.start_child/2 which we can't address due to
backwards compatibility.
Earlier it was throwing `ArithmeticError` which seems confusing, instead
now it will fail on function clause which should give user better
feedback that the arguments are in wrong order.
Benchee.run(
%{
"flatten" => fn ->
Enum.map(1..100_000, fn x -> List.duplicate(x, 1000) end) |> List.flatten()
end,
"flat_map" => fn -> Enum.flat_map(1..100_000, fn x -> List.duplicate(x, 1000) end) end,
"new" => fn -> New.flat_map(1..100_000, fn x -> List.duplicate(x, 1000) end) end
}, memory_time: 5
)
Results:
Operating System: macOS
CPU Information: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
Number of Available Cores: 8
Available memory: 16 GB
Elixir 1.13.0-dev
Erlang 24.0
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 5 s
parallel: 1
inputs: none specified
Estimated total run time: 36 s
Benchmarking flat_map...
Benchmarking flatten...
Benchmarking new...
Name ips average deviation median 99th %
new 0.119 8.43 s ±0.00% 8.43 s 8.43 s
flat_map 0.117 8.55 s ±0.00% 8.55 s 8.55 s
flatten 0.0952 10.50 s ±0.00% 10.50 s 10.50 s
Comparison:
new 0.119
flat_map 0.117 - 1.01x slower +0.125 s
flatten 0.0952 - 1.25x slower +2.07 s
Memory usage statistics:
Name Memory usage
new 2.98 GB
flat_map 4.47 GB - 1.50x memory usage +1.49 GB
flatten 2.98 GB - 1.00x memory usage +0.00150 GB
This improves unclear errors that result in the case where a
custom protocol is passed as the inspect_fun option, and that
protocol is not implemented for some of the types being inspected.
Missing struct implementations are a pathological case here, because
when trying to inspect them as maps, a seemingly unrelated error
message about a missing atom implementation will be reported, while
trying to inspect the value of the :__struct__ field
When the `unmatched_returns` option of Dialyzer is enabled, functions
which can return more than a single value must be explicitly matched
against. This fixes `Kernel.tap/2` to be compatible with that option.