Skip to content
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

Break when best possible filter result found #648

Merged
merged 2 commits into from
Nov 26, 2024

Conversation

andrews05
Copy link
Collaborator

@andrews05 andrews05 commented Nov 26, 2024

I had this sudden idea for a tiny optimisation: For heuristic filter strategies, skip checking remaining filters if we find we have the best possible result. We can do this for MinSum, Entropy, Bigrams, and BigEnt, but not Brute.
For most images this will have little-to-no impact, but for some such as the test file "palette_1_should_be_palette_1.png" (where most lines are all zeros) we can see a 20% performance improvement at o2 and 10% at o5.

Copy link
Collaborator

@AlexTMjugador AlexTMjugador left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, it looks great now! Feel free to merge after rebasing and once CI passes 🤞

@andrews05 andrews05 merged commit 1efacac into shssoichiro:master Nov 26, 2024
12 checks passed
@andrews05 andrews05 deleted the best-result branch November 26, 2024 11:52
@ace-dent
Copy link

Sorry- if this seems obvious- but how is the best possible result determined?

@AlexTMjugador
Copy link
Collaborator

AlexTMjugador commented Nov 26, 2024

Sorry- if this seems obvious- but how is the best possible result determined?

I think it's determined from the Shannon's source coding theorem, assuming that the entropy is as ideal as it can get, which is the case for rows with a single constant value. See also this random Reddit topic with less mathy discussion about it.

Edit: to be more clear, not all heuristic filter selection policies implemented in Oxipng are based on entropy. In any case, the best result is chosen to be the optimal size value that can be computed according to the heuristic.

@TPS
Copy link

TPS commented Nov 26, 2024

I love the concept (& sheer nerdliness) of this — thanks, @andrews05 & @AlexTMjugador! — but is there way to cheaply determine & disable automatically when this shouldn't be used? (E.g., perhaps when random/static or photographic images?) Or is the overhead truly so negligible that's not relevant?

@andrews05
Copy link
Collaborator Author

For each delta filter, the heuristic strategies apply the filter to the current line and then run an algorithm to produce a single value. They then choose the filter based on which one produced the "best" value.

MinSum chooses the one with the smallest value and for this algorithm the smallest possible value for any line is 0.
Bigrams is similar but the smallest possible value is 1.
Entropy and BigEnt choose the largest value and the maximum possible value can be calculated from the length of the line.

To be clear, the best possible value is always deterministic and it's not possible for this change to have any impact on the output file size. It's purely a performance gain that will occur if all bytes in the line are zero. (In retrospect, I could have just checked for this up front and picked the None filter automatically. I might play around with that...)

AlexTMjugador pushed a commit that referenced this pull request Nov 28, 2024
#648 may have been a bit hasty - I realised afterward that there's a
simpler way to achieve the same thing, and include the Brute filter as
well.

This reverts #648 and instead just picks None up front if the line is
all zeros. This is guaranteed to be the chosen filter for MinSum,
Entropy, Bigrams and BigEnt. It's almost certainly true for Brute as
well but this is harder to prove. I've tested this across hundreds of
images and found no change in output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants