Giter Club home page Giter Club logo

fast-hilbert's Introduction

Fast Hilbert

Build Status doc crates.io usage license

Fast Hilbert 2D curve computation using an efficient Lookup Table (LUT) and only considering the lowest order for a given input.

h1 h2 h3 h4 h5 h6

  • Convert from discrete 2D space to 1D hilbert space and reverse
  • Generalized for different unsigned integer input types (thanks DoubleHyphen PR#3)
  • Speedup via lowest order computation (thanks DoubleHyphen PR#2)
  • Very fast using an efficient 512 Byte LUT
  • No additional dependency

Benchmarking the conversion from full 256x256 discrete 2D space to the 1D hilbert space, shows that fast_hilbert more than twice as fast compared to the fastest 2D hilbert transformation libs written in rust. Benchmarked on a Intel i5-6400 CPU @ 2.70 GHz, 4 Cores with 8 GB RAM:

Library Time Description
fast_hilbert 0.7 ms Optimized for fast computation in 2D discrete space using an efficient LUT
hilbert_2d 2.5 ms Also allows other variants such as Moore and LIU
hilbert_curve 2.0 ms Implements algorithm described on Wikipedia
hilbert 32.1 ms Allows computation of higher dimensional Hilbert curves

Especially for higher orders fast_hilbert outperforms other libraries by using only the next lowest relevant order instead of computing the hilbert curve bit per bit for the given input. See PR #2 and #9 for more details.

For example the computation of xy2h(1, 2, 64) is very fast to compute using fast_hilbert compared to a higher x,y pair such as xy2h(u32::MAX-1, u32::MAX-2, 64):

Library x=1, y=2, order=64 x=u32::MAX-1, y=u32::MAX-2, order=64
fast_hilbert 4 ns 32 ns
hilbert_2d 73 ns 72 ns
hilbert_curve 67 ns 49 ns
hilbert 690 ns 680 ns

fast-hilbert's People

Contributors

becheran avatar doublehyphen avatar finnbear avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fast-hilbert's Issues

`num-traits` `v0.2.0` dependency is too old

num-traits v0.2.0, which fast-hilbert depends on, doesn't support impl PrimInt for u128 but fast-hilbert requires it.

This caused a compilation error:

| error[E0277]: the trait bound `u128: PrimInt` is not satisfied
|   --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/fast_hilbert-1.0.0/src/lib.rs:59:16
|    |
| 59 |     type Key = u128;
|    |                ^^^^ the trait `PrimInt` is not implemented for `u128`
|    |
|    = help: the following other types implement trait `PrimInt`:
|              i16
|              i32
|              i64
|              i8
|              isize
|              u16
|              u32
|              u64
|            and 2 others
| note: required by a bound in `Unsigned::Key`

I'll send a PR to fix this! 🚀

90 re-orientation on iteration breaks locality property.

I've been using this (awesome) library for generating Hilbert locations in building a map tiling engine. As the README states, for every zoom, the Hilbert curve rotates. A core property of the Hilbert curve is that relative position of items in the curve is maintained as the zoom changes. For example, this property should hold:

lower_zoom_hilbert = hilbert / (4^n) * (4^n-1)

Or more nicely:

lower_zoom_hilbert = hilbert >> 2

Because the rotation happens, these nice properties do not apply. I instead have to calculate a Hilbert location at a higher zoom and shift down for a lower zoom tile.

Is it possible to tweak the LUT so that this rotation does not happen?

z3 x4 y3 h31
z2 x2 y1 h13
z1 x1 y0 h1

Here we are with a tile at zoom 1. The hilbert location resolves to 1.
Screen Shot 2022-10-28 at 9 12 46 PM

At zoom 2, the hilbert location resolves to 13 due to the rotation.
Screen Shot 2022-10-28 at 9 15 07 PM

If I were to sort geographic data by their Hilbert location at one zoom, the locality will change for another, negating the static quadtree.

And then one more zoom in, and the direction of the preceding tile comes from the north.
Screen Shot 2022-10-28 at 9 18 38 PM

Benchmarking against, and possibly supplementing, `lindel`

  1. Could you also include the lindel crate in the benchmarks you produce? Mr Chernoch's code has some… inefficiencies, let's say, which I took upon myself to correct. I don't think it'll come anywhere remotely close to your own speed, but I also suspect it'll at least fall within the same ball-park as the other crates.
  2. One of the parametres to your functions is the so-called “order” of the Hilbert curve. Correct me if I'm wrong: I think that in your specific case all that matters is whether the order is an even or odd number. Is this indeed what's happening?
  3. Do you have any idea if the tricks you used here can be generalised for arbitrary dimensions? I suspect that generalising them to eg u8s or u16s would be trivial, but the part about the arbitrary dimensions will take a bit more thought methinks.

Thanks in advance!

Get rid of `state` to improve performance (…failed?)

I thought I'd try to figure out a way to get rid of the state parametre in both the LUT's index and the results it outputs. I succeeded in achieving that, but to my astonishment it ended up consistently ~50% slower! I tried optimising things further here and there, but no consistent result came up. Here is the main.rs file that explains how I did all those things; in the lib.rs file you'll see the actual methods I used.

That said…

You said in your benchmarks that fast_hilbert is around 2-2.5 times faster than other comparable methods. My own benchmarks show the improvement to be on the order of 8-10 times faster! I strongly suspect that our benchmarks lead to different results. Thus, if this seems interesting to you, feel free to experiment as well and see; otherwise, just close the issue.

PS: The main reason I ultimately decided to show you the work I did is because I think that this will help illuminate the way to generalise to other dimensions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.