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

Improve how DecodeStream handles empty buffers. #5025

Merged
merged 1 commit into from
Jul 13, 2014

Conversation

nnethercote
Copy link
Contributor

DecodeStream currently initializes its |buffer| field to |null|, which
is reasonable, because lots of DecodeStreams never need to instantiate a
buffer. But this requires various special cases in the code.

This patch change it so DecodeStreamClosure has a single empty
Uint8Array which gets shared between all buffers upon initialization.
This avoids the special cases.

DecodeStream.prototype.ensureBuffer() is really hot, and this removes a
test from the fast path. For one 226 page scanned document this sped up
rendering by about 2%.

DecodeStream currently initializes its |buffer| field to |null|, which
is reasonable, because lots of DecodeStreams never need to instantiate a
buffer. But this requires various special cases in the code.

This patch change it so DecodeStreamClosure has a single empty
Uint8Array which gets shared between all buffers upon initialization.
This avoids the special cases.

DecodeStream.prototype.ensureBuffer() is really hot, and this removes a
test from the fast path. For one 226 page scanned document this sped up
rendering by about 2%.
@CodingFabian
Copy link
Contributor

what is the risk of accidentally writing to the empty buffer?
How does one do immutability in JavaScript? Could you unset the modifying methods of the instance?

@nnethercote
Copy link
Contributor Author

In a typed array, if you read from out-of-bounds elements, you get undefined. If you write to out-of-bounds elements, nothing happens. Those operations shouldn't be happening, but even if they do, it's not a problem (well, not a problem beyond the fact that there's an underlying defect anyway).

Firefox's nsTArray has a similar optimization -- there's a single shared header used for empty arrays. That's where I got the idea.

@CodingFabian
Copy link
Contributor

ok, got it, you are saying because you inited it with zero length it will never contain data. thats good.
So the PR does eliminate some checkings which are no longer needed because at least the empty array exists. and the other places which deal with existing content would put a new appropriately sized array into the variable.
looks good to me. 2% sounds quite a lot for this change. What kind of document would benefit from this? so i can try to verify the improvement.

@nnethercote
Copy link
Contributor Author

That's right; if a bigger buffer is needed it will be allocated on demand.

Any document that uses CCITTFaxStreams heavily would be a good test, because ensureBuffer() is called for every input byte in such streams. I tested with http://njn.valgrind.org/Decontamination.pdf.

@CodingFabian
Copy link
Contributor

I like that change.
I can confirm the improvement (used your document pages 1-200 in 10 rounds)

browser stat Count Baseline(ms) Current(ms) +/- % Result(P<.05)
chrome35 Overall 2000 141 137 -4 -2.71 faster
chrome35 Page Request 2000 3 3 0 4.83
chrome35 Rendering 2000 138 134 -4 -2.88 faster

@Snuffleupagus
Copy link
Collaborator

/botio test

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

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

Live output at: http://107.21.233.14:8877/984acca3150d725/output.txt

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

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

Live output at: http://107.22.172.223:8877/6c5380298dfb162/output.txt

@pdfjsbot
Copy link

From: Bot.io (Linux)


Success

Full output at http://107.21.233.14:8877/984acca3150d725/output.txt

Total script time: 36.79 mins

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

Snuffleupagus added a commit that referenced this pull request Jul 13, 2014
Improve how DecodeStream handles empty buffers.
@Snuffleupagus Snuffleupagus merged commit 0237d50 into mozilla:master Jul 13, 2014
@Snuffleupagus
Copy link
Collaborator

Thanks for the patch!

@nnethercote nnethercote deleted the share-zero-length-buffers branch August 6, 2014 00:42
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