-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Fast access #500
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
Fast access #500
Conversation
3c54463
to
4614211
Compare
On the topic of micro-optimizing the |
This actually looks really good. |
7f8fdc9
to
8ad3e1a
Compare
Indeed, we should use it in xtensor. |
fail_dim_check(sizeof...(index), "too many indices for an array"); | ||
return get_byte_offset(index...); | ||
template<typename... Ix> size_t offset_at(Ix... index) const { | ||
check_dimensions(index...); |
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.
This seems wrong? Note that the check here is for >
whereas in other places it is for !=
, otherwise it would have been implemented like you suggest here via a check_dimensions(...)
helper.
} | ||
|
||
size_t get_byte_offset() const { return 0; } |
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 guess I'd still prefer to have a separate byte_offset_unchecked()
which would be used by all other methods (and xtensor), and having all other methods (including byte_offset()
) be checked, so it's 'safe by default'.
0dfff62
to
5363c56
Compare
5363c56
to
b7c48a1
Compare
So now |
Looks good. #500 (comment) still stands though :) How about this? template<size_t dim = 0, typename... Ix> size_t byte_offset_unchecked(size_t i, Ix... index) const
{ /* current impl, checks nothing */ }
template<typename... Ix> size_t byte_offset(Ix... index) const {
if (sizeof...(index) > ndim())
fail_dim_check(sizeof...(index), "too many indices for an array");
check_dimensions(index...);
return byte_offset_unchecked(index...);
} |
ok, either that or |
(the reasoning being: |
Ideally, I see unsafe version as one that's longer to type and that has a scary suffix like "unsafe" / "unchecked" / w/e, which also conveys the fact that it's "non-default". Since the difference is that it skips bounds checking, "_unchecked" makes sense, imo. |
I agree that any function callable directly from python should be safe and not crash the interpreter for any parameter value, but in the present case, accessors are only to be used from c++. It is usual for c++ container to be unchecked (like |
Agreed. But we're trying to mirror |
Least surprise: If most functions are checked by default, it's natural to assume they all are. Making just one silently unsafe will cause issues for users. |
I disagree with you guys, but I made the change here to get this part through. I will open another issue for discussion on this point and something else that came up. |
template<size_t dim = 0, typename... Ix> size_t byte_offset(size_t i, Ix... index) const { | ||
return i * strides()[dim] + byte_offset<dim + 1>(index...); | ||
template<typename... Ix> size_t byte_offset(Ix... index) const { | ||
check_dimensions(index...); |
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.
Dimensionality check, too? (<
)
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.
There was none originally.
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.
Shall we add one then?
fc5840e
to
6efcac5
Compare
Btw: it's all quite trivial, but adding a test for |
Btw, it is protected, not public. |
Ah, true, apologies. All in all lgtm I think, great bikeshedding :) |
Sorry, I also missed the protected bit. |
Yea, viewing diffs on iPhone is hard, sorry :) To reiterate, the public API we really want to be safe by default, if it's protected then it could just stay unchecked of course. Or, you could have both like now and make the unsafe one public as well, whichever makes most sense. |
👍 |
@wjakob we cannot test this function externally because it is not public. Only thing we could do in the test is inherit from it and expose a public function that calls it. However this is already pretty much what offset_at` does. And it is already tested. |
Got it. Does it make sense to add a dimensionality test? (see the code review comments) |
There was not such check before. The current state of the PR is functionally equivalent to the previous one, but should be faster. |
Well my code is functionnally 5 On Nov 15, 2016 10:47 AM, "Wenzel Jakob" [email protected] wrote:
|
Yes, but since you are already changing that code and moving tests around, it would be nice to fix this omission :) |
Also there are already checks for != and < (depending on the case) in the That would be duplicating the checks. |
Just realized this is not merged yet. Is there any blocker? |
What I don't understand is why the dimensionality check in |
Because they differ depending of the function. Some check for dimension inequality and other for dimension mismatch. This was one of the items of the review by aldanor. |
Ok, I think I get it now -- thanks! |
Cool thanks! |
A first take at the recursive version of access operators + moving the dimension checks up the call stack.
Trying to respect your code formatting conventions.
Closes #497 .