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.
Usage
6 ulid::ULID ulid = ulid::Create(1484581420, []() { return 4; });
7 std::string str = ulid::Marshal(ulid);
8 std::cout << str << '\n'; // 0001C7STHC0G2081040G208104
API
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
void ulid::EncodeNowRand(time_t, const std::function<uint8_t()>&, ULID&)
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.
void ulid::UnmarshalBinaryFrom(const uint8_t[26], ULID&)
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.
Benchmarks
From https://travis-ci.org/suyash/ulid/jobs/196587557
ulid_uint128
1 ./ulid_uint128_bench.out --benchmark_out_format=console
2 Run on (32 X 2800.27 MHz CPU s)
4 Benchmark Time CPU Iterations
5 ---------------------------------------------------------------
6 EncodeTime 20 ns 20 ns 33878597
7 EncodeTimeNow 22 ns 22 ns 32218636
8 EncodeTimeSystemClockNow 153 ns 153 ns 4490317
9 EncodeEntropy 198 ns 198 ns 3562142
10 EncodeEntropyRand 121 ns 121 ns 5780498
11 EncodeEntropyMt19937 525 ns 525 ns 1331004
12 Encode 213 ns 213 ns 3290697
13 EncodeNowRand 139 ns 139 ns 5059356
14 Create 232 ns 232 ns 3028591
15 CreateNowRand 141 ns 141 ns 4943666
16 MarshalTo 39 ns 39 ns 18024722
17 Marshal 93 ns 93 ns 7460186
18 MarshalBinaryTo 19 ns 19 ns 37735347
19 MarshalBinary 133 ns 133 ns 5242484
20 UnmarshalFrom 68 ns 68 ns 10145291
21 Unmarshal 131 ns 129 ns 5659895
22 UnmarshalBinaryFrom 64 ns 64 ns 10402550
23 UnmarshalBinary 216 ns 216 ns 3233510
24 Time 12 ns 12 ns 57538180
25 CompareULIDs 10 ns 10 ns 69390812
ulid_struct
1 ./ulid_struct_bench.out --benchmark_out_format=console
2 Run on (32 X 2800.27 MHz CPU s)
4 Benchmark Time CPU Iterations
5 ---------------------------------------------------------------
6 EncodeTime 11 ns 11 ns 68024343
7 EncodeTimeNow 14 ns 14 ns 53810497
8 EncodeTimeSystemClockNow 141 ns 141 ns 5011618
9 EncodeEntropy 185 ns 185 ns 3756190
10 EncodeEntropyRand 212 ns 212 ns 3289057
11 EncodeEntropyMt19937 485 ns 485 ns 1442392
12 Encode 197 ns 197 ns 3562101
13 EncodeNowRand 220 ns 220 ns 3195564
14 Create 204 ns 204 ns 3404090
15 CreateNowRand 229 ns 229 ns 3057854
16 MarshalTo 41 ns 41 ns 17229969
17 Marshal 96 ns 96 ns 7278924
18 MarshalBinaryTo 19 ns 19 ns 37625620
19 MarshalBinary 134 ns 134 ns 5254147
20 UnmarshalFrom 38 ns 38 ns 18270269
21 Unmarshal 99 ns 99 ns 7048231
22 UnmarshalBinaryFrom 19 ns 19 ns 37479143
23 UnmarshalBinary 175 ns 175 ns 4180657
24 Time 18 ns 18 ns 39717910
25 CompareULIDs 20 ns 20 ns 33980240