kip

kip

ex_cldr Core Team

Tz_world / timezone_boundary_builder update

tz_world is a library that maps a location (lat, lng) to a timezone.

From time-to-time the base data in timzone_boundary_builder is updated based upon updates to the IANA timezone database.

With the IANA timezone database being updated to version 2020a on April 23rd, timezone_boundary_builder has now also updated its release.

For current users of tz_world you can update the data source in two ways:

  1. Run mix tz_world.update
  2. In a running system, call TzWorld.reload_timezone_data/0. Application restart is not required - the new data is downloaded and installed in the running system.

Most Liked

kip

kip

ex_cldr Core Team

I have refactored tz_world to separate different backend strategies. Please feel free to give it a try, I plan to release a new version on hex later this week.

New Backend Access modules

  • TzWorld.Backend.Memory which retains all data in memory for fastest performance at the expense of using approximately 1Gb of memory
  • TzWorld.Backend.Dets which uses Erlang’s :dets data store. This uses negligible memory at the expense of slow access times (approximaltey 500ms in testing)
  • TzWorld.Backend.DetsWithIndexCache which balances memory usage and performance. This backend is recommended in most situations since its performance is similar to TzWorld.Backend.Memory (about 5% slower in testing) and uses about 25Mb of memory
  • TzWorld.Backend.Ets which uses :ets for storage. With the default settings of :compressed for the :ets table its memory consumption is about 512Mb but with access that is over 20 times slower than TzWorld.Backend.DetsWithIndexCache

Most interesting is that by caching the bounding boxes in memory, the backend TzWorld.Backend.DetsWithIndexCache looks to be a good balance of memory utilisation and performance. It uses only ~20Mb of memory to store the bounding boxes and has performance similar to the in-memory backend.

Basic Benchmark

Name                                 ips        average  deviation         median         99th %
Backend Memory                     52.34       19.10 ms    ±14.86%       18.34 ms       30.62 ms
Backend DetsWithIndexCache         50.10       19.96 ms    ±13.15%       20.79 ms       24.66 ms
Backend Ets                         2.33      428.53 ms     ±2.51%      432.73 ms      441.58 ms
Backend Dets                        0.59     1693.80 ms     ±9.62%     1646.47 ms     2018.27 ms

Comparison: 
Backend Memory                     52.34
Backend DetsWithIndexCache         50.10 - 1.04x slower +0.85 ms
Backend Ets                         2.33 - 22.43x slower +409.43 ms
Backend Dets                        0.59 - 88.66x slower +1674.70 ms
kip

kip

ex_cldr Core Team

It’s been a year since any functional updates or bug fixes for tz_world so today I published tz_world version 1.0.0.

Really, the only change is the version number. Still actively maintained, just no open issues or functional enhancement requests.

kip

kip

ex_cldr Core Team

Yep, turns out its really big (and this is the version not including geo data for the oceans).

I will, for the next release:

  1. Turn the storage and access mechanisms into a behaviour
  2. Implement a :dets backend (first priority)
  3. Implement a PostGis backend (which was already written by the original author of tz_world)
  4. Implement a non-PostGis backend for filtering by bounding box

Probably going to take a couple of weeks to get this done.

Thanks for the vigilance @LostKobrakai.

kip

kip

ex_cldr Core Team

Fixed a few bugs, updated the documentation to reflect @lostkobrakai’s suggestion and added an even faster backend TzWorld.Backend.EtsWithIndexCache which is about 40% faster than TzWorld.Backend.Memory although it does take about 512Mb. Results:

Name                                 ips        average  deviation         median         99th %
Backend EtsWithIndexCache          73.37       13.63 ms    ±20.09%       13.81 ms       19.01 ms
Backend Memory                     51.67       19.35 ms    ±14.90%       18.50 ms       29.64 ms
Backend DetsWithIndexCache         49.23       20.31 ms    ±13.60%       21.18 ms       25.44 ms
Backend Ets                         2.25      444.57 ms     ±2.05%      445.87 ms      456.08 ms
Backend Dets                        0.54     1853.16 ms    ±23.09%     1684.00 ms     2726.35 ms

Comparison: 
Backend EtsWithIndexCache          73.37
Backend Memory                     51.67 - 1.42x slower +5.72 ms
Backend DetsWithIndexCache         49.23 - 1.49x slower +6.68 ms
Backend Ets                         2.25 - 32.62x slower +430.94 ms
Backend Dets                        0.54 - 135.97x slower +1839.53 ms

Other improvements:

  • Dialyzer is now also happy.
  • Removed a compile-time expression that would break releases
  • Consolidated the documentation in the TzWorld module

Unless any nasty bugs pop up I’ll release to hex in about 24 hours.

kip

kip

ex_cldr Core Team

Version 0.4.0 has been published on hex. From the changelog

Breaking change

  • When specifying a lng, lat to TzWorld.timezone_at/2 the coordinates must be wrapped in a tuple. For example TzWorld.timezone_at({3.2, 45.32}) making it consistent with the Geo.Point and Geo.PointZ strategies.

Configurable backends

  • TzWorld.Backend.Memory which retains all data in memory for fast (but not fastest) performance at the expense of using approximately 1Gb of memory. Generally not recommended.
  • TzWorld.Backend.Dets which uses Erlang’s :dets data store. This uses negligible memory at the expense of slow access times (approximaltey 500ms in testing)
  • TzWorld.Backend.DetsWithIndexCache which balances memory usage and performance. This backend is recommended in most situations since its performance is similar to TzWorld.Backend.Memory (about 5% slower in testing) and uses about 25Mb of memory
  • TzWorld.Backend.Ets which uses :ets for storage. With the default settings of :compressed for the :ets table its memory consumption is about 512Mb but with access that is over 20 times slower than TzWorld.Backend.DetsWithIndexCache
  • TzWorld.Backend.EtsWithIndexCache which uses :ets for storage with an additional in-memory cache of the bounding boxes. This still uses about 512Mb but is faster than any of the other backends by about 40%

Enhancements

  • Add TzWorld.all_timezones_at/2 to return all timezones for a given location. In rare cases, usually disputed territory, multiple timezones may be declared for overlapping regions. TzWorld.all_timezones_at/2 returns a (potentially empty) list of all time zones known for a given point. Futher testing of this function is required and will be completed before version 1.0.

Where Next?

Popular in Libraries Top

RobertDober
Earmark is a pure-Elixir Markdown converter. It is intended to be used as a library (just call Earmark.as_html), but can also be used as...
239 11851 134
New
tmbb
I’ve been working on two packages (not on hex.pm yet) to build admin interfaces for phoenix apps: bureaucrat - which contains a bunch ...
New
josevalim
EDIT: since Ecto 3.0 final version is out, this post was amended to use the final versions in the instructions below. Hi everyone, We a...
New
mindok
What is ContEx? A pure Elixir server-side data plotting/charting library outputting SVG. It has nice barcharts in particular and works g...
New
New
wfgilman
I’ve cleaned up and open sourced three financial libraries I was using for my company. They are bindings for the APIs of these three comp...
New
Qqwy
Solution is a library to help you with working with ok/error-tuples in case and with-expressions by exposing special matching macros, as ...
New
aditya7iyengar
Rummage.Ecto and Rummage.Phoenix provide ways to perform Searching, Sorting and Pagination over Ecto queries and Phoenix collections. Fo...
New
tmbb
I’ve decided to create this topic to discuss optimization possibilities for something like Phoenix LiveView. I’ve created this topic unde...
New
anshuman23
Hello all, I have been working on my proposed project called Tensorflex as part of Google Summer of Code 2018.. Tensorflex can be used f...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

Sub Categories:

We're in Beta

About us Mission Statement