#include #include #include #include #include #include #include #include const std::size_t N = 1 << 12; // 4K char s[N]; // 4KB struct s_init_t { s_init_t() { std::random_device device; std::default_random_engine generator(device()); std::uniform_int_distribution distribution('0', 'z'); auto rng = [&]() { return distribution(generator); }; std::ranges::generate(s, rng); s[N - 1] = '\0'; } } s_init; std::size_t strlen1(char *str) { std::size_t len = 0; while (*str++ != '\0') ++len; return len; } std::size_t strlen2(char *str) { const char *tmp = str; while (*str != '\0') ++str; return str - tmp; } std::size_t strlen3(char *str) { const char *tmp = str; while (*str++ != '\0') ; return str - tmp - 1; } std::size_t strlen4(const char *str) { std::size_t i = 0; for (; str[i] != '\0'; ++i) ; return i; } std::size_t strlen5(const char *s) { if (*s == '\0') return 0; else return strlen5(s + 1) + 1; } std::size_t strlen6(const char *s) { if (*s == '\0') return 0; else return 1 + strlen6(s + 1); } std::size_t strlen7(char *s) { std::size_t len = 0; for (;;) { unsigned x = *(unsigned *)s; if ((x & 0x000000FF) == 0) return len + 0; if ((x & 0x0000FF00) == 0) return len + 1; if ((x & 0x00FF0000) == 0) return len + 2; if ((x & 0xFF000000) == 0) return len + 3; len += 4, s += 4; } } std::size_t strlen8(const char *s) { unsigned x = *(unsigned *)s; if ((x & 0x000000FF) == 0) return 0; if ((x & 0x0000FF00) == 0) return 1; if ((x & 0x00FF0000) == 0) return 2; if ((x & 0xFF000000) == 0) return 3; return strlen8(s + 4) + 4; } std::size_t strlen9(char *s) { std::size_t len = static_cast(-1); asm volatile("xor %%eax, %%eax \n\t" "repne scasb \n\t" "not %0 \n\t" "dec %0 \n\t" : "+c"(len), "+D"(s) : : "rax", "memory"); return len; } std::size_t strlen10(const char *s) { return std::ranges::count_if(std::string_view{s}, [](char c) { return c != '\0'; }); } template static void test(benchmark::State &state) { assert(f(s) == strlen(s)); for (auto _: state) benchmark::DoNotOptimize(f(s)); state.SetLabel("strlen=" + std::to_string(f(s))); state.SetBytesProcessed(state.iterations() * N); } BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK(test)->Iterations(10'000); BENCHMARK_MAIN();