wy-ei commented on PR #768:
URL:
https://github.com/apache/incubator-kvrocks/pull/768#issuecomment-1211606587
@PragmaTwice
Throwing exception is more than 100 times slower than return error code, If
the probability of throwing exception is less than 1/100, the cost of throwing
exception can be ignored.
I run the benchmark in [1] on my machine, here is the result:
```
Run on (8 X 24.1247 MHz CPU s)
CPU Caches:
L1 Data 64 KiB
L1 Instruction 128 KiB
L2 Unified 4096 KiB (x8)
Load Average: 4.60, 3.61, 3.14
----------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------
BM_exitWithBasicException 356 ns 356 ns 1949354
BM_exitWithMessageException 423 ns 412 ns 1812467
BM_exitWithReturn 3.09 ns 3.09 ns 218084841
BM_exitWithErrorCode 3.04 ns 3.04 ns 233471081
```
In this benchmark, the exception was thrown every two function calls, but
in real situation, exception unlikely be thrown this often.
I change the benchmark code to make the exception be thrown every 200
function calls. (change the variable `randomRange` to 200),and run benchmark
again, here is the result:
```
Run on (8 X 24.1216 MHz CPU s)
CPU Caches:
L1 Data 64 KiB
L1 Instruction 128 KiB
L2 Unified 4096 KiB (x8)
Load Average: 3.45, 2.54, 3.10
----------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------
BM_exitWithBasicException 6.78 ns 6.78 ns 75871712
BM_exitWithMessageException 7.03 ns 7.03 ns 99061744
BM_exitWithReturn 2.98 ns 2.98 ns 235143942
BM_exitWithErrorCode 2.98 ns 2.98 ns 234956097
```
Since throwing exception is a small part of the code, in real situation, I
think the cost of exception is not a big problem.
> So I don't think it's a good idea to use exceptions on some execution path
that is not a very low probability error or is user controllable.
If user input cause error, then error may occur with high probability, use
exception would be inefficient. In this situation, some pre check code can be
added to return error fast, and comparing with disk and network read and
write, the cost of exception is not the main part.
> Another defect is that C++ does not have checked exception, this makes
exception flows not easy to maintain. In addition, it is not easy to ensure the
exception safety of the program, which requires the programmer to have a deep
background knowledge of C++.
C++ do not force user catch the exception, but if you miss an exception the
process will crash. We can ignore an error status, and something weird
happened, but we didn't known the reason. If we keep using RAII, the exception
safety can almost be ensure.
I mentioned exception here because I was think is there another way to deal
with error instead Status. I think both exception and status are ok. But using
exception in kvrocks will break the consistency of the function design (return
Status and pass result as a pointer in last argument), I think this will be a
big change, and I except this won't happed in the near future.
I was off topic for a long time, Back to Status and StatusOr.
In kvrocks, Status class is a large object which include a std::string in
it. The Status class implemented in leveldb only take 8 bytes (only one member
which is const char *state_). If status is ok, state_ is nullptr, if status
is not ok, the state_ store the error code and error message. If we change the
Status implementation in kvrocks to the leveldb way, the size of Status is not
a problem.
Another problem of Status for me is it occupy the place of the return value,
we must pass a pointer to take the return value. Golang solve this problem by
returning multi value. A sample and easily understand way is return a tuple
or another Class will contain return value T and status.
For StatusOr I have one question. StatusOr use a char[] to store T or
Status, I don't known why, why don't use union?
C++23 std::expected [2] is used to contains expected value or an error, does
this a more generic way, Can we implement same thing like this. We can combine
Status and the expected class do the things StatusOr does.
[1] https://pspdfkit.com/blog/2020/performance-overhead-of-exceptions-in-cpp
[2] https://en.cppreference.com/w/cpp/header/expected
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]