Skip to content

Commit

Permalink
Various fixes (#102)
Browse files Browse the repository at this point in the history
- Cleaned up the code a little by running Clippy in pedantic mode
  - Made the code a little more Rust-like by implmenting the `Default` trait for some structs.
- Added `--lon` as an alias for `--lng`
- Allow negative numbers for latitude and longitude, meaning we can go to the southern and western hemispheres.
  • Loading branch information
evensolberg committed Aug 19, 2023
1 parent 8e7160a commit 05157f3
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 150 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog

All notable changes to this project will be documented in this file.

## [0.4.2] - 2023-07-31

### Chore

- Update Cargo lock

## [0.2.1] - 2023-01-25

### Bug Fixes

- Pprof can not build on windows (#36)

<!-- generated by git-cliff -->
56 changes: 28 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license = "MIT"
name = "tzf-rs"
readme = "README.md"
repository = "https://github.com/ringsaturn/tzf-rs"
version = "0.4.3"
version = "0.4.4"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
35 changes: 14 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# tzf-rs: a fast timezone finder for Rust. [![Rust](https://github.com/ringsaturn/tzf-rs/actions/workflows/rust.yml/badge.svg)](https://github.com/ringsaturn/tzf-rs/actions/workflows/rust.yml) [![Documentation](https://docs.rs/tzf-rs/badge.svg)](https://docs.rs/tzf-rs)

![](https://github.com/ringsaturn/tzf/blob/gh-pages/docs/tzf-social-media.png?raw=true)
![Time zone map of the world](https://github.com/ringsaturn/tzf/blob/gh-pages/docs/tzf-social-media.png?raw=true)

**NOTE**: this package use a simplified shape data so not so accurate around
border.
**NOTE**: This package uses simplified shape data so it is not entirely accurate around the border.

## Build options

By default, the binary is built as well. If you don't want/need it, then build
like this:
By default, the binary is built as well. If you don't want/need it, you can omit the default features and build like this:

```bash
cargo build --no-default-features
Expand All @@ -20,10 +18,10 @@ Or add in the below way:
cargo add tzf-rs --no-default-features
```

## Best practice
## Best Practices

It's expensive to init tzf-rs's Finder/FuzzyFinder/DefaultFinder, please
consider reuse it or as a global var. Below is a global var example:
It's expensive to init tzf-rs's `Finder`/`FuzzyFinder`/`DefaultFinder`, so please
consider reusing instances or creating one as a global variable. Below is a global variable example:

```rust
use lazy_static::lazy_static;
Expand All @@ -39,33 +37,28 @@ fn main() {
}
```

For reuse it,
[`racemap/rust-tz-service`](https://github.com/racemap/rust-tz-service) is a
good example.
For reuse, [`racemap/rust-tz-service`](https://github.com/racemap/rust-tz-service) provides a good example.

A Redis protocol demo could be used here:
[`ringsaturn/redizone`](https://github.com/ringsaturn/redizone).
A Redis protocol demo could be used here: [`ringsaturn/redizone`](https://github.com/ringsaturn/redizone).

## Performance

The tzf-rs package is intended for high-performance geo spatial query services,
The tzf-rs package is intended for high-performance geospatial query services,
such as weather forecasting APIs. Most queries can be returned within a very
short time, averaging around 3000 nanoseconds(there is 1000ns slower compared
with Go repo `tzf` and I will continue to improve that, you can track progress
short time, averaging around 3,000 nanoseconds (about 1,000ns slower than
with Go repo `tzf`. I will continue improving this - you can track progress
[here](https://github.com/ringsaturn/geometry-rs/issues/3)).

Here is what has been done to improve performance:

1. Using pre-indexing to handle most queries takes approximately 1000
nanoseconds.
1. Using pre-indexing to handle most queries takes approximately 1000 nanoseconds.
2. Using a finely-tuned Ray Casting algorithm package
[`ringsaturn/geometry-rs`](https://github.com/ringsaturn/geometry-rs) to
verify whether a polygon contains a point.

That's all. There are no black magic tricks inside the tzf-rs.

Below is a benchmark run on global cities(about 14K), and avg time is about 3000
ns per query:
Below is a benchmark run on global cities(about 14K), and avg time is about 3,000 ns per query:

```txt
test benches_default::bench_default_finder_random_city ... bench: 2,870 ns/iter (+/- 182)
Expand All @@ -81,7 +74,7 @@ You can view more details from latest benchmark from

## References

I have written an article about the history of tzf, its Rust port, and its Rust
I have written an article about the history of `tzf`, its Rust port, and its Rust
port's Python binding; you can view it
[here](https://blog.ringsaturn.me/en/posts/2023-01-31-history-of-tzf/).

Expand Down
8 changes: 4 additions & 4 deletions benches/finders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use rand::seq::SliceRandom;
use tzf_rs::{DefaultFinder, Finder};

lazy_static! {
static ref DEFAULT_FINDER: DefaultFinder = DefaultFinder::new();
static ref FINDER: Finder = Finder::new();
static ref DEFAULT_FINDER: DefaultFinder = DefaultFinder::default();
static ref FINDER: Finder = Finder::default();
}

fn bench_default_finder_random_city(_i: usize) {
Expand All @@ -28,10 +28,10 @@ fn bench_finders(c: &mut Criterion) {

let i = &0;
group.bench_with_input(BenchmarkId::new("Default", i), i, |b, _i| {
b.iter(|| bench_default_finder_random_city(black_box(1)))
b.iter(|| bench_default_finder_random_city(black_box(1)));
});
group.bench_with_input(BenchmarkId::new("Finder", i), i, |b, _i| {
b.iter(|| bench_finder_random_city(black_box(1)))
b.iter(|| bench_finder_random_city(black_box(1)));
});

group.finish();
Expand Down
3 changes: 1 addition & 2 deletions benches/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
#[cfg(test)]
mod benches_default {

use cities_json;
use tzf_rs::DefaultFinder;
extern crate test;
use test::Bencher;
#[bench]
fn bench_default_finder_random_city(b: &mut Bencher) {
let finder: DefaultFinder = DefaultFinder::new();
let finder: DefaultFinder = DefaultFinder::default();

b.iter(|| {
let city = cities_json::get_random_cities();
Expand Down
4 changes: 2 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ fn main() {
Some(_) => prost_build::Config::new()
.out_dir("src/gen/")
.compile_protos(&["./tzinfo.proto"], &["."])
.unwrap(),
.unwrap_or_default(),
None => println!("no need for pb"),
}

Command::new("cargo")
.args(&["fmt", "--", "src/*.rs"])
.args(["fmt", "--", "src/*.rs"])
.status()
.expect("cargo fmt failed");
}
7 changes: 4 additions & 3 deletions src/bin/tzf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ use tzf_rs::DefaultFinder;
#[command(name = "tzf")]
struct Cli {
/// longitude
#[arg(long)]
#[arg(long, allow_negative_numbers(true), alias("lon"))]
lng: f64,

/// latitude
#[arg(long)]
#[arg(long, allow_negative_numbers(true))]
lat: f64,
}

pub fn main() {
let cli = Cli::parse();
let finder = DefaultFinder::new();
println!("{:?}", finder.get_tz_name(cli.lng, cli.lat));
let tz_name = finder.get_tz_name(cli.lng, cli.lat);
println!("{tz_name:?}");
}
4 changes: 2 additions & 2 deletions src/gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ impl TryFrom<Vec<u8>> for Timezones {
type Error = anyhow::Error;

fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
Ok(Timezones::decode(&value[..])?)
Ok(Self::decode(&value[..])?)
}
}

impl TryFrom<Vec<u8>> for PreindexTimezones {
type Error = anyhow::Error;

fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
Ok(PreindexTimezones::decode(&value[..])?)
Ok(Self::decode(&value[..])?)
}
}
Loading

0 comments on commit 05157f3

Please sign in to comment.