-
Notifications
You must be signed in to change notification settings - Fork 33
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
Implement "perfect" waking for tuple::merge
#96
Implement "perfect" waking for tuple::merge
#96
Conversation
oh, I almost forgot the perf result
|
288bcce
to
b39fe19
Compare
tuple::merge
tuple::merge
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 looks great! -- I'm adding you as a reviewer, so feel free to merge this PR yoursel!
// poll the `streams.{index}` stream | ||
utils::tuple_for_each!(poll_stream (index, this, streams, cx, LEN) $($F)*); |
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.
Oh this is really nice!
impl_merge_tuple! { merge9 Merge9 A B C D E F G H I } | ||
impl_merge_tuple! { merge10 Merge10 A B C D E F G H I J } | ||
impl_merge_tuple! { merge11 Merge11 A B C D E F G H I J K } | ||
impl_merge_tuple! { merge12 Merge12 A B C D E F G H I J K L } |
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.
A little nit: macro-highlighting is basically impossible to do well in Rust, but to simplify it for treesitter (the library used by github and lots of editors), we could make the input to this and other macros something like this:
$mod_name: ident :: $StructName: ident <$($F: ident),+>
That's not a blocker at all though, I just like the idea of using common Rust syntax so that macros are both easier to read and highlights.
Of course the issue here would be that MergeX
is not really in the mergeX
module, just wanted to get the idea out here :)
I have another idea to improve getting the index from a tuple value, let me try it, I think it will fail statically (e.g. |
The main idea is using macro_rules! tuple_indexes {
($mod_name:ident :: $StructName:ident < $($F:ident),+ >) => {
mod $mod_name {
// Ensure indexes are in increasing order and start at 0 while being
// very cheap to generate for the macro.
//
// If you want to ensure there are 256 elements or less, use repr(u8)
#[repr(usize)]
pub enum Indexes {
$($F),+
}
pub const TUPLE_LEN: usize = match [$(Indexes::$F),+] {
[.., last] => last as usize + 1,
};
}
#[derive(Default)]
pub struct $StructName {
state: [bool; $mod_name::TUPLE_LEN],
}
impl $StructName {
$(
#[allow(non_snake_case)]
pub fn $F(&self) -> (usize, bool) {
// For this simple example could be inlined, but if used multiple times,
// having a separate branch for clarity is nice
let index = tuple_indexes!(@index of $mod_name :: $F);
(index, self.state[index])
}
)+
}
};
(@index of $mod_name: ident :: $F: ident) => {
$mod_name::Indexes::$F as usize
};
}
tuple_indexes!(test_1 :: Test1 < A >);
tuple_indexes!(test_2 :: Test2 < A, B >);
tuple_indexes!(test_3 :: Test3 < A, B, C >);
#[test]
fn expected_indexes() {
let t = Test1::default();
assert_eq!(t.A().0, 0);
let t = Test2::default();
assert_eq!(t.A().0, 0);
assert_eq!(t.B().0, 1);
let t = Test3::default();
assert_eq!(t.A().0, 0);
assert_eq!(t.B().0, 1);
assert_eq!(t.C().0, 2);
} This could be used to simplify the macros, making rustc do less work ^^ |
that's a very interesting approach, @poliorcetics! I'll merge this PR as it is now, but I would like to see a scratch PR integrating your ideas - I think it would be very fair to see you in the contributors list! |
b39fe19
to
33a10da
Compare
Done in #99 :) I'll try to run the benchmarks on my side to see if it helped |
This mimics the implementation for
array::merge
.I used that hack I introduced on #74 in a more generalized form, we can rewrite the
gen_conditions
in terms of this new macro (basically the same way I do here)Ref #21