-
Notifications
You must be signed in to change notification settings - Fork 47
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
ValueBox #114
ValueBox #114
Conversation
I think CI was already failing before my PR, so these failures aren't something I need to fix? |
Hi @martindevans. Thanks again for putting this up! I'll try to get this reviewed shortly. The CI failure is indeed an existing problem in |
@martindevans if you rebase your PR on main, that should resolve the test failures. |
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.
These changes look good to me, just a few comments to address.
Regarding this approach and its drawbacks, I think it's beneficial enough to justify any breaking changes around passing arguments existing users might encounter.
Obviously some sort of function wrapping where we can return a callable object where the argument type checks are elided for the actual call would be most ideal. If you want to take a stab at that approach, I'd be happy to review it in lieu of or in addition to merging this.
…only used for function arguments) without any heap allocated boxing. - Added `ValueBox` - Removed `object` based `Invoke` calls in `Function`
Co-authored-by: Peter Huene <peter@huene.dev>
- Added back in appropriate code style - Modified `ValueBox` for `object` to accept `null`
5991d67
to
24c7e22
Compare
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.
👍 looks good to merge.
Would you like this to go in now or would you like to instead wait for taking the alternative approach of returning Func
-like wrappers that elide the parameter / result conversions and type checking?
We may as well leave this PR for a couple of days, just in case I need to make any major changes to it to support the Func-wrapper approach. |
So far I didn't have to make any changes to this for my #116 draft PR, so I think it's probably safe to merge it as is. I don't mind if you'd rather wait and do it all in one go though :) |
…earer API instead of hijacking an existing type.
Instead of using |
I agree, that is much nicer! Sorry, I've been out sick this week, so I haven't been responding to GitHub notifications. Please let me know if you want me to review this again and merge it if it's needed for the other PR. |
That's no problem, I hope you're feeling better now :) Please go ahead and review this and merge it if you're happy with it. The other PR builds on top of both changes this introduces. |
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.
Just a comment or two and a few nits. Looking really great!
- Added doc comments to V128 constructor - Renamed generic `Value` field to slightly more useful `bytes` - Using span copying instead of a handwritten loop
I've addressed all of that feedback |
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.
Excellent, thanks again for this work!
See proposal #113.
To reduce allocations for boxing on every call this PR introduces a new
ValueBox
struct which wraps up arguments without requiring any heap allocations. Currently this is only used for function arguments, but in principle it could be used anywhere else plain oldobject
references are passed around (e.g. function returns values).Drawbacks
ValueBox
is mostly invisible to the end user since things convert to it with an implict conversion. However, C# does not support user defined conversions fromobject
so that has to be done with an explicit conversion method - i.e. passingmy_ref_object
becomesValueBox.AsBox(my_ref_object)
. I've added an implict conversion for strings, since that's likely to be a fairly common case. Unfortunately I don't see a better way to handle this situation for any other references types.I had to remove the old
params object[]
method, since it confliced with the newparams ValueBox[]
method, which is a breaking API change. If you'd rather not much such a big change to the external API I can instead removeparams ValueBox[]
and require that users call it explicitly with aReadOnlySpan<ValueBox>
instead.params ValueBox[]
still incurs a single allocation, which can be worked around by explicitly passing in aReadOnlySpan<ArgBox>
, but that's not very ergonomic.I haven't done anything with return types at all, they still get boxed. It's not obvious how to fix them, since the caller does not supply the return type.
Potential Improvements
We could potentially workaround a lot of the drawbacks above by introducing a new set of generic
GetFunction
overloads which returnFunc<>
orAction<>
objects. This would have quite a few benefits:GetFunction
is called, instead of whenInvoke
is called. Potentially reducing per-call overhead.ValueBox
can be done inside theFunc
/Action
which is returned, making it invisible to the end user (ValueBox.AsBox
doesn't need to be called externally)Func
/Action
object.If you're interested I can put together another PR which does this (don't merge this PR if so).