[core] Add a util for size literals#48638
Conversation
Signed-off-by: dentiny <dentinyhao@gmail.com>
rynewang
left a comment
There was a problem hiding this comment.
LGTM, but can we make at least one usage in code base to avoid dead code and to showcase? src/ray/stats/metric_defs.cc can be a good start.
src/ray/util/size_literals.h
Outdated
| constexpr unsigned long long operator""_PiB(unsigned long long sz) { | ||
| return sz * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL; | ||
| } | ||
| constexpr unsigned long long operator""_PB(unsigned long long sz) { |
There was a problem hiding this comment.
why do we use long long instead of size_t
There was a problem hiding this comment.
I don't see much difference?
unsigned long longis the largest unsigned range we could have in C++ natively- we won't have negative value here
There was a problem hiding this comment.
ofc they are the same: size_t is just typedef of unsigned long long on 64bit system. However it has a clearer semantics: it represents a size, which is what all these "number of bytes" about.
There was a problem hiding this comment.
No strong preference, updated.
There was a problem hiding this comment.
OK, I found size_t doesn't compile
./src/ray/util/size_literals.h:22:18: error: 'constexpr size_t operator""_B(size_t)' has invalid argument list
22 | constexpr size_t operator""_B(size_t sz) { return sz; }
| ^~~~~~~~
Working version:
constexpr unsigned long long operator""_B(unsigned long long sz) { return sz; }
Non-workable version:
constexpr size_t operator""_B(size_t sz) { return sz; }
src/ray/util/size_literals.h
Outdated
|
|
||
| #include <cstdint> | ||
|
|
||
| constexpr unsigned long long operator""_PiB(unsigned long long sz) { |
There was a problem hiding this comment.
wrap everything in namespace ray::literals so users must opt-in with using
There was a problem hiding this comment.
I don't think putting these function into a namespace is a good idea.
For example, gflag requires all flag values to placed in outmost namespace.
A typical use case is:
DEFINE_int64(some_flag_name, 15_MiB, "some flag description");
Signed-off-by: dentiny <dentinyhao@gmail.com>
rynewang
left a comment
There was a problem hiding this comment.
Also since we are here - is it possible to define a class ByteSize { size_t bytes_; static operator""_KiB(...){...} } so we can be more type rich? Just discussion - did not research on how big this is.
src/ray/util/size_literals.h
Outdated
|
|
||
| constexpr unsigned long long operator""_B(unsigned long long sz) { return sz; } | ||
|
|
||
| constexpr unsigned long long operator""_KiB(unsigned long long sz) { |
There was a problem hiding this comment.
[nit] I'd prefer ordering as B, KB, MB,...., KiB, MiB, ....
Sure, updated one place for metrics defs. |
src/ray/util/size_literals.h
Outdated
There was a problem hiding this comment.
[nit] why not:
constexpr size_t operator""_PiB(long double sz) {
const long double res = sz * 1_PiB;
return static_cast<size_t>(res);
}
There was a problem hiding this comment.
and these double-to-size_t code are so duplicated, I wonder if we can make it a macro.
// Macro to generate (long double -> size_t) literal from (size_t -> size_t)
#define CREATE_FLOAT_SIZE_LITERAL(suffix) \
constexpr size_t operator""_##suffix(long double sz) { \
return static_cast<size_t>(sz * 1_##suffix); \
}
// Using the macro to define long double -> size_t literals
CREATE_FLOAT_SIZE_LITERAL(KiB)
CREATE_FLOAT_SIZE_LITERAL(MiB)
CREATE_FLOAT_SIZE_LITERAL(GiB)
CREATE_FLOAT_SIZE_LITERAL(TiB)
CREATE_FLOAT_SIZE_LITERAL(PiB)
There was a problem hiding this comment.
[nit] why not:
constexpr size_t operator""_PiB(long double sz) {
const long double res = sz * 1_PiB;
return static_cast<size_t>(res);
}
Updated.
There was a problem hiding this comment.
I'm not a fan of macros.
Using macro is generally not recommended (effective C++ item-1 has a few good arguments):
- Hard to debug, easier to get wrong;
- Purely textual replacement, no compiler check (i.e. what if repeated macro definition);
- Affective, especially in header file.
I almost only use macros at error propagation (i.e. ray/util/logging.h) to save some boilerplate code for unhappy path.
For here, both implementations are just one-liner, don't see much benefit.
Emm could you please give me some examples you think it's better to have such class? |
Signed-off-by: dentiny <dentinyhao@gmail.com>
267eeef to
3b8640d
Compare
Signed-off-by: dentiny <dentinyhao@gmail.com>
Signed-off-by: dentiny <dentinyhao@gmail.com>
Signed-off-by: dentiny <dentinyhao@gmail.com>
Signed-off-by: dentiny <dentinyhao@gmail.com>
Signed-off-by: dentiny <dentinyhao@gmail.com>
As titled, I think having `MB` explicitly called out is more readable than `1024 * 1024` or `1<<20` Intended use case: ray-project#48262 (comment) Signed-off-by: dentiny <dentinyhao@gmail.com>
As titled, I think having
MBexplicitly called out is more readable than1024 * 1024or1<<20Intended use case: #48262 (comment)