Skip to content

Colorspace: refactoring to prevent unnecessary creation of intermediate arrays #7863

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

Merged
merged 3 commits into from
Dec 6, 2016

Conversation

timvandermeij
Copy link
Contributor

@timvandermeij timvandermeij commented Dec 1, 2016

This commit series refactors the colorspace code to prevent the creation of unnecessary intermediate arrays and to make the code shorter and more readable. The commit messages contain more information about the changes.

Reviewing is slightly easier with https://github.com/mozilla/pdf.js/pull/7863/files?w=1.

Copy link
Collaborator

@Snuffleupagus Snuffleupagus left a comment

Choose a reason for hiding this comment

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

Really nice that you've decided to try and make colorspace.js more efficient!

I'm including a benchmark of the changes, [...], each with 6 runs.

The jsPerf results certainly seem convincing, but I've got one question here.
I'm well aware that those files are slow to render, but unfortunately 6 runs is way to low to be able to say with any certainty whether a change really improves performance (since statistically the sample size is way too low, an individual test run could actually skew the final results).
Would you be able to run the tests with at least 25 (or even 50) runs each?

@@ -294,13 +294,10 @@ var ColorSpace = (function ColorSpaceClosure() {
}

cs = xref.fetchIfRef(cs);
var mode;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I cannot help wondering if it isn't more efficient to use a local variable, rather than adding something to this that will not actually be used outside of this particular method?
Couldn't this actually increase memory usage, albeit a very tiny bit, since you're now (unnecessarily) storing more state?
Have you benchmarked this particular change to see if it really helps?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the new commit. Now that you mentioned this, I also noticed that it's not used outside of this method, so it may just as well be only local.

@@ -606,7 +606,7 @@ var DeviceGrayCS = (function DeviceGrayCSClosure() {
getRgbItem: function DeviceGrayCS_getRgbItem(src, srcOffset,
dest, destOffset) {
var c = (src[srcOffset] * 255) | 0;
c = c < 0 ? 0 : c > 255 ? 255 : c;
c = Math.min(Math.max(c, 0), 255);
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Dec 2, 2016

Choose a reason for hiding this comment

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

Would it make sense, as in would it help the JS engine to optimize these computations even further, if this code was moved to e.g. a clamp function placed at the top of this file (or even a utility function to be used in more files)?

Also, I noticed that in LabCS clamping is still done the old way.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's been awhile since I looked at this, but using an inline conditional use to always be faster. If I remember correctly, we actually removed calls to clamp an inlined the clamping.

Copy link
Contributor Author

@timvandermeij timvandermeij Dec 2, 2016

Choose a reason for hiding this comment

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

Fixed in the new commit. I created a utility function for clamping and used that in all places for clarity. I fixed the clamping in LabCS as well. There is one last manual clamping part in LabCS, but since that uses a different kind of clamping (first to a [0,1] range and then to a [0,255] range in one step), I did not find a suitable way to convert that to use the clamp function and not break functionality, so I propose we leave that one instance as-is.

@@ -748,7 +748,8 @@ var DeviceCmykCS = (function DeviceCmykCSClosure() {
function DeviceCmykCS() {
this.name = 'DeviceCMYK';
this.numComps = 4;
this.defaultColor = new Float32Array([0, 0, 0, 1]);
this.defaultColor = new Float32Array(this.numComps);
this.defaultColor[3] = 1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: maybe some sort of comment would be good here, since it might not be immediately clear why the "standard" this.defaultColor = new Float32Array(this.numComps); isn't enought in this particular case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the new commit.

This patch avoids the creation of extra arrays when initializing an
array with default (zero) values. Doing this additionally makes the code
more readable by allocating enough space for the number of color
components.
- Remove an unnecessary check and assignment.
- Clean up code regarding mode setting (no need for a member variable).
- Indent two methods correctly.
@timvandermeij timvandermeij force-pushed the colorspace branch 2 times, most recently from 2508325 to 06fae58 Compare December 2, 2016 18:56
@brendandahl
Copy link
Contributor

Reposting...It's been awhile since I looked at this, but using an inline conditional use to always be faster. If I remember correctly, we actually removed calls to clamp an inlined the clamping.

@timvandermeij timvandermeij changed the title Colorspace: improve performance Colorspace: refactoring to prevent unnecessary creation of intermediate arrays Dec 6, 2016
@timvandermeij
Copy link
Contributor Author

timvandermeij commented Dec 6, 2016

I removed the commit with the clamping code as its performance impact is hard to measure objectively and it's unclear if the additional function call is bad or not (even though the code is more readable). This can be done later as it would otherwise unnecessarily delay landing of the other commits.

@Snuffleupagus Would you be willing to review this patch as well? It's now only a clean-up PR that won't have a performance impact anymore (only slight memory usage reduction because of the arrays, but it's probably not even measurable).

@timvandermeij
Copy link
Contributor Author

/botio-linux preview

@pdfjsbot
Copy link

pdfjsbot commented Dec 6, 2016

From: Bot.io (Linux)


Received

Command cmd_preview from @timvandermeij received. Current queue size: 0

Live output at: http://107.21.233.14:8877/7f2f58e7c247fb8/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Dec 6, 2016

From: Bot.io (Linux)


Success

Full output at http://107.21.233.14:8877/7f2f58e7c247fb8/output.txt

Total script time: 2.12 mins

Published

@timvandermeij
Copy link
Contributor Author

/botio test

@pdfjsbot
Copy link

pdfjsbot commented Dec 6, 2016

From: Bot.io (Linux)


Received

Command cmd_test from @timvandermeij received. Current queue size: 0

Live output at: http://107.21.233.14:8877/cd48698caf2a980/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Dec 6, 2016

From: Bot.io (Windows)


Received

Command cmd_test from @timvandermeij received. Current queue size: 0

Live output at: http://107.22.172.223:8877/fd0998037b4af25/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Dec 6, 2016

From: Bot.io (Windows)


Success

Full output at http://107.22.172.223:8877/fd0998037b4af25/output.txt

Total script time: 26.17 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

@pdfjsbot
Copy link

pdfjsbot commented Dec 6, 2016

From: Bot.io (Linux)


Success

Full output at http://107.21.233.14:8877/cd48698caf2a980/output.txt

Total script time: 27.39 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

Copy link
Collaborator

@Snuffleupagus Snuffleupagus left a comment

Choose a reason for hiding this comment

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

Seems fine to me, thanks for the clean-up!

@Snuffleupagus Snuffleupagus merged commit 94ddd8f into mozilla:master Dec 6, 2016
@timvandermeij timvandermeij deleted the colorspace branch December 6, 2016 21:23
movsb pushed a commit to movsb/pdf.js that referenced this pull request Jul 14, 2018
Colorspace: refactoring to prevent unnecessary creation of intermediate arrays
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants