-
Notifications
You must be signed in to change notification settings - Fork 30
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
Low level optimizations for contiguous sequences #103
Low level optimizations for contiguous sequences #103
Conversation
@tcbrindle I filled this PR to see if I'm on the right track (any feedback much appreciated) and also to make it know that the work is in progress for that particular issue. |
Thanks for working on this! It looks like there's a syntax error which is tripping up the non-Windows builds, but the general approach looks good to me 👍 |
6a3c81e
to
2a1a5f3
Compare
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #103 +/- ##
==========================================
+ Coverage 97.58% 97.70% +0.12%
==========================================
Files 66 67 +1
Lines 2276 2398 +122
==========================================
+ Hits 2221 2343 +122
Misses 55 55
☔ View full report in Codecov by Sentry. |
2a1a5f3
to
f1848c9
Compare
I've noticed that with the {
auto sv = "the quick brown fox"sv;
auto split = flux::split(flux::ref(sv), ' ');
using S = decltype(split);
static_assert(flux::multipass_sequence<S>);
static_assert(flux::contiguous_sequence<flux::element_t<S>>);
static_assert(flux::multipass_sequence<S const>);
static_assert(flux::contiguous_sequence<flux::element_t<S const>>);
STATIC_CHECK(check_equal(std::move(split).map(to_string_view),
std::array{"the"sv, "quick"sv, "brown"sv, "fox"sv}));
} |
Just looking for an initial round of feedback; I'll have to address the build issues. |
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 are quite a few comments, but several of them are just minor style things.
This is looking in pretty good shape, we just need to make sure that the conditions for using the specialisations is correct in each case. I'd rather err on the side of caution -- it's better to use a potentially slower code path than give the wrong answer or (worse) end up with UB.
There do seem to be a lot of unnecessary, unrelated formatting changes though -- I guess from clang-format messing things up? I started marking them but gave up as there are quite a few... Please put these lines back to how they were originally so that the diff only includes meaningful changes.
This is caused by the new specialisation of |
Fill now uses `std::memset` for single byte values when not constant evaluated. Also added a unit test for this specific case.
Also moved `any_of` concept to `utils`
9e66c2d
to
77e9c39
Compare
I believe I've addressed most, if not all of your comments. Unit tests are also all passing for me. Please take another look when you have a moment. Thanks! |
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 is looking really good! There's only one change still outstanding, namely the definition of can_memset
in fill.hpp
Whoops! I missed that, thanks! |
f7cc097
to
7d6301f
Compare
For auto const seq1_size = flux::usize(seq1);
auto const seq2_size = flux::usize(seq2);
auto min_size = std::min(seq1_size, seq2_size);
int cmp_result = 0;
if (min_size > 0) {
auto const data1 = flux::data(seq1);
FLUX_ASSERT(data1 != nullptr);
auto const data2 = flux::data(seq2);
FLUX_ASSERT(data2 != nullptr);
cmp_result = std::memcmp(data1, data2, min_size);
} That is, we only call the C function if the number of bytes is greater than zero, also making sure that the data pointers are not nullptr. This is getting messier and messier, sorry! |
4016f3a
to
be189ff
Compare
Ok I think this is ready now and all tests pass for me! |
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 can simplify the test in equal(), because we already know that both sequences are the same size. Other than that, just a couple of tiny code style things.
CodeCov is complaining that the new "size == 0" code-paths aren't being tested, so it's probably worth adding a couple of little tests to cover this -- but I'm happy to do it if you've had enough of this PR already!
Also, it looks like the new compare() specialisation isn't actually reached by any of the existing tests... This definitely needs rectifying before we can commit this, but again, I'm happy to add some unsigned char compare() tests if you don't fancy it.
Made a silly blunder.
I was able to add some tests, but not sure if I covered everything you had in mind. I also address all (I think) your feedback from the latest review. Sorry for the silly oversights at times and thanks for all the feedback! |
Looks like I didn't cover all the cases for |
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.
All the actual implementation code looks great now!
compare()
is still missing a couple of test cases, I've made some suggestions below.
CodeCov is also complaining that we're not testing the case of two zero-length contiguous sequences in equal()
. Something like
std::array<int, 0> arr;
STATIC_CHECK(flux::equal(arr, arr) == true);
in test_equal.cpp should keep it happy I think?
Done! |
It's done!! 🎉 Thanks so much! |
Description
Adds low level optimizations to address #57
Optimizations
std::memset
withfill()
std::memcmp
withequal()
std::memcmp
withcompare()
std::memchr
withfind()
std::memmem
withsearch()