Skip to content

Commit ccfc04e

Browse files
lemireanonrig
authored andcommitted
Let us avoid to_string(x).size().
1 parent 8036960 commit ccfc04e

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

include/ada/url-inl.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#include "ada/url_components.h"
1111
#include <optional>
1212
#include <string>
13+
#if ADA_REGULAR_VISUAL_STUDIO
14+
#include <intrin.h>
15+
#endif // ADA_REGULAR_VISUAL_STUDIO
1316

1417
namespace ada {
1518
[[nodiscard]] ada_really_inline bool url::includes_credentials() const noexcept {
@@ -77,6 +80,39 @@ namespace ada {
7780
return out << u.to_string();
7881
}
7982

83+
// number of 'leading zeroes'.
84+
inline int leading_zeroes(uint32_t input_num) {
85+
#if ADA_REGULAR_VISUAL_STUDIO
86+
unsigned long leading_zero(0);
87+
unsigned long in(input_num);
88+
return _BitScanReverse(&leading_zero, in) ? int(31 - leading_zero) : 32;
89+
#else
90+
return __builtin_clz(input_num);
91+
#endif// ADA_REGULAR_VISUAL_STUDIO
92+
}
93+
94+
// integer logarithm of x (ceil(log2(x)))
95+
inline int int_log2(uint32_t x) {
96+
return 31 - leading_zeroes(x | 1);
97+
}
98+
99+
// faster than std::to_string(x).size().
100+
inline int fast_digit_count(uint32_t x) {
101+
// Compiles to very few instructions. Note that the
102+
// table is static and thus effectively a constant.
103+
// We leave it inside the function because it is meaningless
104+
// outside of it (this comes at no performance cost).
105+
const static uint64_t table[] = {
106+
4294967296, 8589934582, 8589934582, 8589934582, 12884901788,
107+
12884901788, 12884901788, 17179868184, 17179868184, 17179868184,
108+
21474826480, 21474826480, 21474826480, 21474826480, 25769703776,
109+
25769703776, 25769703776, 30063771072, 30063771072, 30063771072,
110+
34349738368, 34349738368, 34349738368, 34349738368, 38554705664,
111+
38554705664, 38554705664, 41949672960, 41949672960, 41949672960,
112+
42949672960, 42949672960};
113+
return (x + table[int_log2(x)]) >> 32;
114+
}
115+
80116
[[nodiscard]] ada_really_inline ada::url_components url::get_components() noexcept {
81117
url_components out{};
82118

@@ -104,7 +140,7 @@ namespace ada {
104140

105141
if (port.has_value()) {
106142
out.port = out.host_end;
107-
out.pathname_start += std::to_string(port.value()).size();
143+
out.pathname_start += fast_digit_count(port.value());
108144
}
109145

110146
if (query.has_value()) {

0 commit comments

Comments
 (0)