An open API service indexing awesome lists of open source software.

https://github.com/partiallywritten/humans-formatter-py

Zig implementation of humans-formatter python extension
https://github.com/partiallywritten/humans-formatter-py

python-extension zig zig-python-bindings

Last synced: 5 days ago
JSON representation

Zig implementation of humans-formatter python extension

Awesome Lists containing this project

README

          

# humans-formatter-py
Re-implementation of my pypi library, [humans-formatter](https://pypi.org/project/humans-formatter/) in zig.

### Usage
```py
import humans

# time formatting
# time(ms: int, compound: bool = True, round: bool = False)
# - Format milliseconds into human readable form. Use only one argument except 'ms' at a time
print(humans.time()

# byte formatting
# bytes(size: int)
# - Convert bytes into human readable KiB/MiB/etc.
print(humans.bytes()

# see docs
print(humans.__doc__)
print(humans.time.__doc__)
print(humans.bytes.__doc__)
```

### Build it

> [!IMPORTANT]
> This extension requires,
> - python 3.13 or newer as it uses [fast calls](https://docs.python.org/3/c-api/structures.html#c.METH_FASTCALL) [^1]
> - zig 0.15.2 (or newer, not tested) as it uses `std.Io.Writer` (see [Writergate update](https://ziglang.org/download/0.15.1/release-notes.html#Writergate))

```sh
zig build-lib -dynamic -O ReleaseFast -I /usr/include/python -femit-bin= -lc wrapper.zig
```
Replace placeholders with
- `python` - Your python version (`python --version`). ex: `python3.14`
- `` - Path to where the `*.so` file needs to be created. ex: `tests/humans.so`

Once you get your `*.so` file, you can just import it in python using `import ` (replace with whatever the name of your .so file without the extension); Assuming they are both in the same directory

### Performance results
Up to **6.5x** speed boost on `humans.time()` and Up to **6.4x** speed boost on `humans.bytes()` compared their python counterparts

Click to See detailed results

```
======== Benchmark ========

[humans.time()]
Runs: 5
Iterations: 3,000,000
Mean total: 0.329832 sec
Best total: 0.327457 sec
Std dev: 0.003686 sec
Mean/op: 109.94 ns
Best/op: 109.15 ns

[humans.bytes()]
Runs: 5
Iterations: 3,000,000
Mean total: 0.374867 sec
Best total: 0.371739 sec
Std dev: 0.003231 sec
Mean/op: 124.96 ns
Best/op: 123.91 ns

[origin.time()]
Runs: 5
Iterations: 3,000,000
Mean total: 2.346812 sec
Best total: 2.323678 sec
Std dev: 0.016030 sec
Mean/op: 782.27 ns
Best/op: 774.56 ns

[origin.bytes()]
Runs: 5
Iterations: 3,000,000
Mean total: 2.641040 sec
Best total: 2.629541 sec
Std dev: 0.012963 sec
Mean/op: 880.35 ns
Best/op: 876.51 ns

[Sample Outputs]
humans.time: 1h 1m 1s
humans.bytes: 1.00 GiB
```

see [bench.py](tests/bench.py) and [python implementation](tests/origin.py) for more info.
Both are optimized and implementations of the same logic

[^1]: It can be compiled on older versions as long as the header file contain necessary signatures and macros