C++ port of oklog/ulid and alizain/ulid.
There are 2 implementations, the first in ulid_uint128.hh
uses a __uint128_t
to represent a ULID.
The second in ulid_struct.hh
encapsulates a 16 byte array in a struct, and uses that to represent a ULID
ulid.hh
essentially (tries to) see if __uint128_t
exists, in which case it imports the definition in ulid_uint128.hh
, otherwise it imports the implementation in ulid_struct.hh
.
The __uint128_t
version seems to be faster, some benchmarks below and more extensive ones on travis.
#include <ulid.hh>
...
ulid::ULID ulid = ulid::Create(1484581420, []() { return 4; });
std::string str = ulid::Marshal(ulid);
std::cout << str << '\n'; // 0001C7STHC0G2081040G208104
The wrapper type for a __uint128_t
/ 16 byte array representing a ULID.
encodes passed time in first 6 bytes of a ULID.
encodes std::time(nullptr)
as time.
encodes std::chrono::system_clock::now()
by taking the timestamp in milliseconds.
sets the last 10 bytes as the values generated using the passed random byte generator.
sets the entropy using std::rand
.
sets the entropy by generating values from a std::mt19937
generator, initializes a std::uniform_int_distribution
on each invocation.
EncodeTime + EncodeEntropy
EncodeTimeNow + EncodeEntropyRand
creates a fresh ULID using the passed timestamp and generator.
Create:Encode::CreateNowRand:EncodeNowRand
Marshals the ulid into the passed character array.
Marshals and generates std::string.
Marshals the ulid into the passed byte array.
Marshals and generates std::vector<uint8_t>.
Unmarshals the passed character array into the ulid.
Creates a new ULID by Unmarshaling the passed string.
Unmarshals the passed byte array into the ulid.
Creates a new ULID by Unmarshaling the passed vector.
Extracts the timestamp used to create the ULID.
Ubuntu Xenial (16.04), clang++-8
From https://travis-ci.org/suyash/ulid/jobs/475187043
ulid_uint128
./ulid_uint128_bench.out --benchmark_out_format=console
2019-01-04 07:11:24
Running ./ulid_uint128_bench.out
Run on (2 X 2500 MHz CPU s)
CPU Caches:
L1 Data 32K (x1)
L1 Instruction 32K (x1)
L2 Unified 256K (x1)
L3 Unified 30720K (x1)
Load Average: 0.98, 0.51, 0.21
--------------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------------
EncodeTime 23.2 ns 23.2 ns 30323833
EncodeTimeNow 26.8 ns 26.7 ns 25925285
EncodeTimeSystemClockNow 96.4 ns 96.4 ns 7366207
EncodeEntropy 209 ns 209 ns 3363959
EncodeEntropyRand 100 ns 100 ns 6875073
EncodeEntropyMt19937 470 ns 469 ns 1481254
Encode 231 ns 231 ns 3022655
EncodeNowRand 128 ns 128 ns 5346738
Create 238 ns 238 ns 2970710
CreateNowRand 133 ns 133 ns 5384520
MarshalTo 37.5 ns 37.5 ns 18655071
Marshal 83.7 ns 83.7 ns 8261322
MarshalBinaryTo 16.7 ns 16.7 ns 41790384
MarshalBinary 157 ns 157 ns 4464307
UnmarshalFrom 64.0 ns 63.9 ns 10822292
Unmarshal 113 ns 113 ns 6146163
UnmarshalBinaryFrom 64.8 ns 64.8 ns 10942429
UnmarshalBinary 248 ns 248 ns 2832217
Time 15.0 ns 15.0 ns 46389021
CompareULIDs 8.44 ns 8.44 ns 83106152
ulid_struct
./ulid_struct_bench.out --benchmark_out_format=console
2019-01-04 07:11:43
Running ./ulid_struct_bench.out
Run on (2 X 2500 MHz CPU s)
CPU Caches:
L1 Data 32K (x1)
L1 Instruction 32K (x1)
L2 Unified 256K (x1)
L3 Unified 30720K (x1)
Load Average: 0.99, 0.54, 0.22
--------------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------------
EncodeTime 9.14 ns 9.13 ns 76851483
EncodeTimeNow 12.6 ns 12.6 ns 55315496
EncodeTimeSystemClockNow 73.5 ns 73.5 ns 9515669
EncodeEntropy 201 ns 201 ns 3480980
EncodeEntropyRand 196 ns 195 ns 3602452
EncodeEntropyMt19937 449 ns 449 ns 1560469
Encode 211 ns 211 ns 3352107
EncodeNowRand 204 ns 204 ns 3493016
Create 217 ns 217 ns 3214903
CreateNowRand 213 ns 213 ns 3271363
MarshalTo 34.1 ns 34.1 ns 20540465
Marshal 80.6 ns 80.5 ns 8743422
MarshalBinaryTo 17.6 ns 17.6 ns 39780449
MarshalBinary 154 ns 154 ns 4503322
UnmarshalFrom 33.3 ns 33.3 ns 20997275
Unmarshal 88.5 ns 88.4 ns 7957903
UnmarshalBinaryFrom 17.0 ns 17.0 ns 41314026
UnmarshalBinary 198 ns 198 ns 3541637
Time 14.9 ns 14.9 ns 46747210
CompareULIDs 20.6 ns 20.6 ns 34150306
For a comparison across latest 3 versions of g++ and clang++ on linux and clang++ on mac, see https://travis-ci.org/suyash/ulid/builds/475187039
The library uses googletest for tests and benchmark as benchmarks, which are built as submodules. In order to get those dependencies, clone recursively, i.e.
git clone -r https://github.com/suyash/ulid