-
-
Notifications
You must be signed in to change notification settings - Fork 706
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
chore(sumtype): avoid quadratic memory complexity on opEquals #8607
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Luís Ferreira <[email protected]>
Thanks for your pull request, @ljmf00! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + phobos#8607" |
I would much, much rather improve One simple optimization we can do is to replace the lambda handler in |
@ljmf00 The style checker fails:
|
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.
As I said in my previous comment: code duplication like this adds to our maintenance burden, and increases the risk of introducing bugs, like the one pointed out in my review comment.
I would strongly prefer it if we could try a less drastic alternative, like replacing the lambda with a global function (as has already been done in SumType
's destructor), before resorting to this.
Finally, if the justification for this change is memory usage, it would be nice to see before-and-after measurements demonstrating the reduction in memory usage. In spite of what the PR title says, both the original and new code have quadratic complexity.
static foreach(ridx, U; typeof(rhs).Types) | ||
{ | ||
case ridx: | ||
static if (is(immutable T == immutable U)) |
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 line introduces a bug. In the original version, the following unit test passes:
@safe unittest
{
int* p = null;
const int* cp = null;
SumType!(int*, const(int*)) x = p;
SumType!(int*, const(int*)) y = cp;
assert(x != y);
}
With this PR, the unit test above will fail.
Update: I tried replacing the lambda with a global function in a local git branch. Unfortunately, for reasons I don't fully understand, this ended up causing forward reference errors for recursive sum types that have |
@pbackus In that case would you recommend moving forward as-is? I know that code duplication is bad, but quadratic memory complexity is worse IMO. |
@LightBender I would be ok with moving forward as long as
As I've pointed out before, both the original and the new version have quadratic complexity, which means that the gain from switching to |
Signed-off-by: Luís Ferreira [email protected]
Due to
match
template being quadratic/exponential in terms of memory complexity, (-vtemplate
reports a rediculous amount of templates) usingopEquals
will generate a lot of unnecessary template instances. Removingmatch
here to prevent that.