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

Algoritmic improvement in Dict #350

Merged
merged 2 commits into from Aug 16, 2015

Conversation

Projects
None yet
2 participants
@jvoigtlaender
Contributor

jvoigtlaender commented Aug 15, 2015

Replaces https://github.com/elm-lang/core/pull/255.

The essence is that calls max (RBNode_elm_builtin c k v l r) are replaced by maxWithDefault k v r, where the improvement is that the latter function is less complicated (fewer arguments, less pattern matching) and does not need an artificial (never triggered) Debug.crash case.

Two further notes:

  • The function min is never called, also not exported, thus could be eliminated.
  • The two functions maxWithDefault and remove_max are always called in parallel, and have the same recursion structure, so could in principle be merged into a single function.

jvoigtlaender added some commits Aug 15, 2015

remove superfluous bindings
... as they were just reconstructing and shadowing already existing
bindings with the exact same values
@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 16, 2015

Member

Awesome, I like this one a lot more, nice refactor!

Member

evancz commented Aug 16, 2015

Awesome, I like this one a lot more, nice refactor!

evancz pushed a commit that referenced this pull request Aug 16, 2015

Merge pull request #350 from jvoigtlaender/dict
Algoritmic improvement in Dict

@evancz evancz merged commit 1106463 into elm:master Aug 16, 2015

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 16, 2015

Member

Let's get rid of min in a PR of its own.

I don't know the code well enough to say on the second one. if you think it's better, it makes sense to me to try it.

Member

evancz commented Aug 16, 2015

Let's get rid of min in a PR of its own.

I don't know the code well enough to say on the second one. if you think it's better, it makes sense to me to try it.

@jvoigtlaender jvoigtlaender deleted the jvoigtlaender:dict branch Aug 16, 2015

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Aug 16, 2015

Contributor

PR for removing min: https://github.com/elm-lang/core/pull/351

About the other potential change (merging maxWithDefault and remove_max), this would really require first having some benchmarking in place. The idea would be to use a classic tupling transformation. That is,

maxWithDefault : k -> v -> Dict k v -> (k, v)

and

remove_max : NColor -> k -> v -> Dict k v -> Dict k v -> Dict k v

would be replaced by

new_function : NColor -> k -> v -> Dict k v -> Dict k v -> ((k, v), Dict k v)

with the understanding that semantically

new_function c k v l r = (maxWithDefault k v r, remove_max c k v l r)

but actually new_function performs only one traversal instead of the two independent traversals of remove_max and maxWithDefault.

In theory, this transformation should always be an improvement, but in practice it shows (at the very least in Haskell, partly due to issues with laziness) that very often it is not. The extra tuples may lead to space overhead, extra construction and deconstruction work, etc.

Contributor

jvoigtlaender commented Aug 16, 2015

PR for removing min: https://github.com/elm-lang/core/pull/351

About the other potential change (merging maxWithDefault and remove_max), this would really require first having some benchmarking in place. The idea would be to use a classic tupling transformation. That is,

maxWithDefault : k -> v -> Dict k v -> (k, v)

and

remove_max : NColor -> k -> v -> Dict k v -> Dict k v -> Dict k v

would be replaced by

new_function : NColor -> k -> v -> Dict k v -> Dict k v -> ((k, v), Dict k v)

with the understanding that semantically

new_function c k v l r = (maxWithDefault k v r, remove_max c k v l r)

but actually new_function performs only one traversal instead of the two independent traversals of remove_max and maxWithDefault.

In theory, this transformation should always be an improvement, but in practice it shows (at the very least in Haskell, partly due to issues with laziness) that very often it is not. The extra tuples may lead to space overhead, extra construction and deconstruction work, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment