diff options
| author | Tyge Løvset <[email protected]> | 2022-04-25 17:12:17 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-04-25 17:12:17 +0200 |
| commit | 72b40c6f5bbfbf11eba112a42ca5536c4c8e7d8f (patch) | |
| tree | c05896fb7bd57855b517f316a8c284127a1f2778 | |
| parent | 09f08e7ac65624d63f1eb04fba2317a2e0b2b0b7 (diff) | |
| download | STC-modified-72b40c6f5bbfbf11eba112a42ca5536c4c8e7d8f.tar.gz STC-modified-72b40c6f5bbfbf11eba112a42ca5536c4c8e7d8f.zip | |
Some maintainance. Updated sso_bench.cpp
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | benchmarks/misc/sso_bench.cpp | 112 | ||||
| -rw-r--r-- | include/stc/alt/cstr.h | 4 |
3 files changed, 58 insertions, 64 deletions
@@ -7,8 +7,10 @@ News: Version 3.5 released (Mar 2022) ------------------------------------- - Swapped to new **cstr** (*short string optimized*, aka SSO). Note that `cstr_str(&s)` must be used, `s.str` is no longer usable. - Added general `i_clone` template parameter: containers with smart pointers (**carc**, **cbox**) can now be correctly cloned. +- Allows for `i_key*` template parameters instead of `i_val*` for all containers, not only for **cset** and **csset**. - Optimized *c_default_hash()*. Therefore *c_hash32()* and *c_hash64()* are removed (same speed). - Added *.._push()* and *.._emplace()* function to all containers to allow for more generic coding. +- Renamed global PRNGs *stc64_random()* and *stc64_srandom()* to *crandom()* and *csrandom()*. - Added some examples and benchmarks for SSO and heterogenous lookup comparison with c++20 (string_bench_*.cpp). Introduction @@ -18,11 +20,11 @@ with a uniform API across the containers, and is similar to the c++ standard lib inspirations from Rust and Python too. It is a compact, header-only library which includes the all the major "standard" data containers except for the -multimap/set variants. However, there are examples on how to create multimaps in the examples folder. +multimap variants. However, there are examples on how to create multimaps in the examples folder. For an introduction to templated containers, please read the blog by Ian Fisher on [type-safe generic data structures in C](https://iafisher.com/blog/2020/06/type-safe-generics-in-c). -Note that STC does not use long macro expansions anymore, but relies on one or more inclusions of the same file, +Note that STC does not use long macro expansions anymore, but relies on one or more inclusion of the same file, which by the compiler is seen as different code because of macro name substitutions. - [***ccommon*** - RAII and iterator macros](docs/ccommon_api.md) diff --git a/benchmarks/misc/sso_bench.cpp b/benchmarks/misc/sso_bench.cpp index 5ff54be9..c123fff6 100644 --- a/benchmarks/misc/sso_bench.cpp +++ b/benchmarks/misc/sso_bench.cpp @@ -1,113 +1,103 @@ #include <string> #include <iostream> #include <vector> +#include <unordered_set> #include <chrono> -#define i_type svec -#define i_val_str -#include <stc/cstack.h> - -#define ROTL_(x, k) (x << (k) | x >> (8*sizeof(x) - (k))) - -static uint64_t g_romutrio[3] = { - 0x26aa069ea2fb1a4dULL, 0x70c72c95cd592d04ULL, - 0x504f333d3aa0b359ULL, -}; - -static inline uint64_t romutrio(void) { - uint64_t *s = g_romutrio, xp = s[0], yp = s[1], zp = s[2]; - s[0] = 15241094284759029579u * zp; - s[1] = yp - xp; s[1] = ROTL_(s[1], 12); - s[2] = zp - yp; s[2] = ROTL_(s[2], 44); - return xp; -} - -static void sromutrio(uint64_t seed) { - uint64_t *s = g_romutrio; - s[0] = 0x26aa069ea2fb1a4dULL + seed; - s[1] = 0x70c72c95cd592d04ULL + seed; - s[2] = 0x504f333d3aa0b359ULL + seed; -} +#include <stc/crandom.h> +#define i_type stccon +#define i_val_str +#include <stc/cvec.h> -static const char CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=+-"; +using stdcon = std::vector<std::string>; static const int BENCHMARK_SIZE = 5000000; -static const int MAX_STRING_LENGTH = 30; - +static const int MAX_STRING_LENGTH = 60; +static const char CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=+-"; using time_point = std::chrono::high_resolution_clock::time_point; -void addRandomString_STD(std::vector<std::string>& vec, const int length) { + +void addRandomString_STD(stdcon& con, int length) { std::string s(length, 0); char* p = &s[0]; + union { uint64_t u8; uint8_t b[8]; } r; for (int i = 0; i < length; ++i) { - p[i] = CHARS[romutrio() & 63]; + if ((i & 7) == 0) r.u8 = crandom() & 0x3f3f3f3f3f3f3f3f; + p[i] = CHARS[r.b[i & 7]]; } - s.append(s); - vec.push_back(std::move(s)); + con.push_back(std::move(s)); } -void addRandomString_STC(svec& vec, const int length) { +void addRandomString_STC(stccon& con, int length) { cstr s = cstr_with_size(length, 0); char* p = cstr_data(&s); + union { uint64_t u8; uint8_t b[8]; } r; for (int i = 0; i < length; ++i) { - p[i] = CHARS[romutrio() & 63]; + if ((i & 7) == 0) r.u8 = crandom() & 0x3f3f3f3f3f3f3f3f; + p[i] = CHARS[r.b[i & 7]]; } - cstr_append_s(&s, s); - svec_push_back(&vec, s); + stccon_push_back(&con, s); } template <class L, typename R> -void benchmark(L& vec, const int length, R addRandomString) { +int benchmark(L& con, const int length, R addRandomString) { time_point t1 = std::chrono::high_resolution_clock::now(); if (length == 0) for (int i = 0; i < BENCHMARK_SIZE; i++) - addRandomString(vec, (i*13 & 31) + 1); + addRandomString(con, (crandom() & 31) + 1); else for (int i = 0; i < BENCHMARK_SIZE; i++) - addRandomString(vec, length); + addRandomString(con, length); time_point t2 = std::chrono::high_resolution_clock::now(); const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(); - std::cerr << length*2 << "\t" << duration; + std::cerr << (length ? length : 16) << "\t" << duration; + return (int)duration; } int main() { uint64_t seed = 4321; - sromutrio(seed); + csrandom(seed); + int sum, n; std::cerr << "length\ttime\tstd::string\n"; for (int k = 0; k < 4; k++) { - std::vector<std::string> vec; vec.reserve(BENCHMARK_SIZE); - benchmark(vec, 0, addRandomString_STD); - std::cout << '\t' << vec[0] << '\n'; + stdcon con; con.reserve(BENCHMARK_SIZE); + benchmark(con, 0, addRandomString_STD); + std::cout << '\t' << *con.begin() << '\n'; } - sromutrio(seed); + csrandom(seed); std::cerr << "\nlength\ttime\tSTC string\n"; for (int k = 0; k < 4; k++) { - svec vec = svec_with_capacity(BENCHMARK_SIZE); - benchmark(vec, 0, addRandomString_STC); - std::cout << '\t' << cstr_str(&vec.data[0]) << '\n'; - svec_drop(&vec); + stccon con = stccon_with_capacity(BENCHMARK_SIZE); + benchmark(con, 0, addRandomString_STC); + std::cout << '\t' << cstr_str(stccon_begin(&con).ref) << '\n'; + stccon_drop(&con); } - sromutrio(seed); - std::cerr << "length\ttime\tstd::string\n"; - for (int length = 1; length <= MAX_STRING_LENGTH; length++) { - std::vector<std::string> vec; vec.reserve(BENCHMARK_SIZE); - benchmark(vec, length, addRandomString_STD); - std::cout << '\t' << vec[0] << '\n'; + csrandom(seed); + sum = 0, n = 0; + std::cerr << "\nlength\ttime\tstd::string\n"; + for (int length = 1; length <= MAX_STRING_LENGTH; length += 2) { + stdcon con; con.reserve(BENCHMARK_SIZE); + sum += benchmark(con, length, addRandomString_STD), ++n; + std::cout << '\t' << *con.begin() << '\n'; } + std::cout << "Avg:\t" << sum/n << '\n'; + - sromutrio(seed); + csrandom(seed); + sum = 0, n = 0; std::cerr << "\nlength\ttime\tSTC string\n"; - for (int length = 1; length <= MAX_STRING_LENGTH; length++) { - svec vec = svec_with_capacity(BENCHMARK_SIZE); - benchmark(vec, length, addRandomString_STC); - std::cout << '\t' << cstr_str(&vec.data[0]) << '\n'; - svec_drop(&vec); + for (int length = 1; length <= MAX_STRING_LENGTH; length += 2) { + stccon con = stccon_with_capacity(BENCHMARK_SIZE); + sum += benchmark(con, length, addRandomString_STC), ++n; + std::cout << '\t' << cstr_str(stccon_begin(&con).ref) << '\n'; + stccon_drop(&con); } + std::cout << "Avg:\t" << sum/n << '\n'; std::cerr << "sizeof std::string : " << sizeof(std::string) << std::endl << "sizeof STC string : " << sizeof(cstr) << std::endl; diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index 437ce5f9..06f8eae1 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -65,12 +65,14 @@ STC_API bool cstr_getdelim(cstr *self, int delim, FILE *stream); STC_API void cstr_replace_all(cstr* self, const char* find, const char* repl);
STC_INLINE cstr cstr_init() { return cstr_null; }
+STC_INLINE const char* cstr_str(const cstr* self) { return self->str; }
#define cstr_toraw(self) (self)->str
+STC_INLINE csview cstr_sv(const cstr* self)
+ { return c_make(csview){self->str, _cstr_p(self)->size}; }
#define cstr_new(literal) \
cstr_from_n(literal, c_strlen_lit(literal))
STC_INLINE cstr cstr_from(const char* str)
{ return cstr_from_n(str, strlen(str)); }
-STC_INLINE const char* cstr_str(const cstr* self) { return self->str; }
STC_INLINE char* cstr_data(cstr* self) { return self->str; }
STC_INLINE size_t cstr_size(cstr s) { return _cstr_p(&s)->size; }
STC_INLINE size_t cstr_length(cstr s) { return _cstr_p(&s)->size; }
|
