-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH-44491: [C++] StatusConstant- cheaply copied const Status #44493
base: main
Are you sure you want to change the base?
Conversation
|
0634658
to
0a5005e
Compare
ARROW_CHECK_NE(code, StatusCode::OK) << "Cannot construct ok status constant"; | ||
} | ||
|
||
operator Status() const { // NOLINT(runtime/explicit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could alternatively make StatusConstant a subclass of Status
@pitrou @felipecrv which benchmark would be convincing as a demonstration this doesn't slow us down? I don't think we have an explicit status or result benchmark For now (since it seems to me to have the deepest Status bubbling stack), @ursabot please benchmark command=cpp-micro --suite-filter=grouper |
We do, but for some reason I had stuffed it in arrow/cpp/src/arrow/type_benchmark.cc Lines 545 to 555 in 1b40800
|
@ursabot please benchmark command=cpp-micro --suite-filter=type |
Benchmark runs are scheduled for commit f7d3fff. Watch https://buildkite.com/apache-arrow and https://conbench.ursa.dev for updates. A comment will be posted here when the runs are complete. |
Thanks for your patience. Conbench analyzed the 3 benchmarking runs that have been run so far on PR commit f7d3fff. There were 4 benchmark results indicating a performance regression:
The full Conbench report has more details. |
Can you check the binary size impact with The performance impact is very tiny but everywhere a |
StatusConstant(StatusCode code, std::string msg, | ||
std::shared_ptr<StatusDetail> detail = nullptr) | ||
: state_{code, std::move(msg), std::move(detail), /*is_constant=*/true} { | ||
ARROW_CHECK_NE(code, StatusCode::OK) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that ARROW_CHECK_NE
is always executed even in non-debug builds, do you want that here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably unnecessary for constants; I was copying from Status::Status
// We can't add context lines to a StatusConstant's state, so copy it now | ||
state_ = new State{code(), message(), detail()}; | ||
} | ||
const_cast<State*>(state_)->msg += ss.str(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did we make the state const
if we need the const_cast
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this to satisfy myself that this line was the only place we ever mutate state_
. I can remove the const
now that I'm sure, but... since this line is the only place we ever mutate state_
, I thought it'd be better to leave it so that in the future if we add another mutation we won't forget to CopyOnWrite any constants
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 on the principle, see comments
@ursabot please benchmark command=cpp-micro --suite-filter=type --benchmark-filter=Error |
Benchmark runs are scheduled for commit 86741d6. Watch https://buildkite.com/apache-arrow and https://conbench.ursa.dev for updates. A comment will be posted here when the runs are complete. |
Thanks for your patience. Conbench analyzed the 3 benchmarking runs that have been run so far on PR commit 86741d6. There were 2 benchmark results indicating a performance regression:
The full Conbench report has more details. |
Those regressions have got to be flukes; they don't even touch Status |
Yes, the code changes probably trigger random variation in code placement in these benchmarks, that could explain the false regressions. |
86741d6
to
d13d04e
Compare
Rationale for this change
It'd be convenient to construct placeholder error Status cheaply.
What changes are included in this PR?
A constant error Status can now be constructed wrapped in a function like
Copying the constant status is relatively cheap (no heap interaction), so it's suitable for use as a placeholder error status.
Added
bool Status::State::is_constant
which causes copies to be shallow and skips destruction. AlsoStatus::state_
is a const pointer now; this helps to ensure that it is obvious when we mutate state_ (as in AddContextLine).Are these changes tested?
Minimal unit test added. The main consideration is probably benchmarks to make sure hot paths don't get much slower.
Are there any user-facing changes?
This API is not currently public; no user-facing changes.