gus
What is the most efficient way to fill a binary with constant values?
Hey all,
As the title says, what do you think is the most efficient way to fill a binary with all constant values? I usually do the following:
for _i <- 1..n, into: "", do: <<0xFF>>
But when using a large-ish number for n, such as 10_000, it takes a couple of seconds to fill the buffer (on my low-powered Nerves device).
The following is actually noticeably faster:
(for _i <- 1..n, do: 0xFF) |> :erlang.list_to_binary
Some timings:
iex(23)> :timer.tc(fn ->
...(23)> for _i <- 1..10_000, into: "", do: <<0xFF>>
...(23)> end)
{1184934,
<<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, ...>>}
iex(24)> :timer.tc(fn ->
...(24)> (for _i <- 1..10_000, do: 0xFF) |> :erlang.list_to_binary
...(24)> end)
{64366,
<<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, ...>>}
That’s a big difference - 1.1 seconds vs 64ms!
I assume the reason for the first one being so slow is because each iteration of the for comprehension does a binary concatenation, whereas the second version appends to the linked list, then accumulates everything at the end into the binary.
This has me wondering - is this the best method for creating large binaries with constant values, or is there something better?
Marked As Solved
LostKobrakai
You can use String.duplicate/2 / :binary.copy/2.
Also Liked
gus
Oh nice, I had no clue those existed! Much faster. Looks like they probably use the same function under the hood:
iex(30)> :timer.tc(fn ->
...(30)> :binary.copy(<<0xFF>>, 10_000)
...(30)> end)
{726,
<<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, ...>>}
iex(32)> :timer.tc(fn ->
...(32)> String.duplicate(<<0xFF>>, 10_000)
...(32)> end)
{724,
<<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, ...>>}
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










