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

Fixes caching of inline images during parsing. #5445

Merged
merged 1 commit into from
Dec 15, 2014

Conversation

CodingFabian
Copy link
Contributor

As described in #5444, the evaluator will perform identity checking of
paintImageMaskXObjects to decide if it can use
paintImageMaskXObjectRepeat instead of paintImageMaskXObjectGroup.

This can only ever work if the entry is a cache hit. However the
previous caching implementation was doing a "lazy" caching, which would
only consider a image cache-worthy if it is repeated.
Only then the repeated instance would be cached.
As a result of this the sequence of identical images A1 A2 A3 A4 would be
seen as A1 A2 A2 A2 by the evaluator, which prevents using the "repeat"
optimization.

Also the previous cache implementation was only checking the last used
image.
Thus the sequence A1 B1 A2 B2 A3 B3 would be 6 instances of images, even
when there are only two different ones.

The new implementation drops the "lazy" init of the cache. The threshold
for enabling an image to be cached is rather small, so the potential waste
in storage and adler32 calculation is pretty low.
Also this implementation will now keep hold of any cachable images. Not
only the last seen image.

The two examples from above would now be A A A A and A1 B1 A1 B1 A1 B1,
which not only saves temporary storage, but also prevents computing
identical masks over and over again (which is the main performance impact
of #2618)

@CodingFabian
Copy link
Contributor Author

for the mentioned pdf, this reduces render times by 50%:

before:

Page: 1
Page Request 148ms
Rendering    3854ms
Overall      4002ms

after:

Page: 1
Page Request 152ms
Rendering    2046ms
Overall      2198ms

@Snuffleupagus
Copy link
Collaborator

/botio-windows test

@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/a9fd94bd2e163ba/output.txt

@pdfjsbot
Copy link

From: Bot.io (Windows)


Failed

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

Total script time: 2.92 mins

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

Image differences available at: http://107.22.172.223:8877/a9fd94bd2e163ba/reftest-analyzer.html#web=eq.log

@CodingFabian
Copy link
Contributor Author

if the time spend calculating the adler32 checksum is an issue for pdfs where the cache is not hit, we could make a cache for candidates by length and then calculate the adler32 lazy if a second image of same length is encountered.
But while it is possible that any pdf is slowed down by the change, i would also say that i believe that any pdf would benefit from the change as well :-)

@Snuffleupagus
Copy link
Collaborator

Did this patch actually pass the regression tests locally?
I noticed that at least tutorial.pdf fails with this patch applied (on Windows and Firefox Nightly 36).

@CodingFabian
Copy link
Contributor Author

Jonas, I do not think this PR is work in progress.
for example the tutorial.pdf renders just fine. I however cannot check a potential windows regression. The windows bot you started needs to be kicked. maybe @yurydelendik can kick it. Can you post me a screenshot of the diff in the meantime?

@CodingFabian
Copy link
Contributor Author

ok, i see it. page 14 for example. strange. my best guess is that the checksumming inst as good as it should be. now that i changed it to alllow more than one entry...
lets see what happens if i change it back to only one entry

@CodingFabian
Copy link
Contributor Author

thanks for the heads up @Snuffleupagus - it really is that the checksumming considers two different images as equal. ugh.

@CodingFabian
Copy link
Contributor Author

according to what i just read about the adler32, i think that checksumming is not really suitable. because my patch causes more images to be potentially reused, the checksum now generates more false positives.
I will update the pr with a more reliable checksumming tomorrow.

@CodingFabian
Copy link
Contributor Author

could we run a linux bot on the current state? besides the adlr32 weakness, i assume that the only regression difference might be due to the binary mask.

@yurydelendik
Copy link
Contributor

/botio-windows test

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

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

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

@pdfjsbot
Copy link

From: Bot.io (Windows)


Failed

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

Total script time: 20.30 mins

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

Image differences available at: http://107.22.172.223:8877/d737f85d40d5df1/reftest-analyzer.html#web=eq.log

@CodingFabian
Copy link
Contributor Author

looks good, doesn't it?

@@ -221,7 +216,7 @@ var Parser = (function ParserClosure() {

imageStream = this.filter(imageStream, dict, length);
imageStream.dict = dict;
if (cacheImage) {
if (adler32) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is a chance 1:2^32 that adler32 can be 0

@yurydelendik
Copy link
Contributor

@yurydelendik
Copy link
Contributor

looks good, doesn't it?

The failures somewhat expected, but we have to be careful.

@CodingFabian
Copy link
Contributor Author

ill measure MurmurHash3_64 and see how it goes.

It takes about twice as long. (for the pdf in question 398ms vs 149ms)

@CodingFabian
Copy link
Contributor Author

i figured it out. it was not the fact that writing in the cache caused the problem. it was the reading part that never assumed more than one entry in it.
i fixed that now and i will stay with the adler32 until proven otherwise.

@yurydelendik
Copy link
Contributor

/botio-windows test

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

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

Live output at: http://107.22.172.223:8877/9adcf0ad2e2ed3c/output.txt

@pdfjsbot
Copy link

From: Bot.io (Windows)


Failed

Full output at http://107.22.172.223:8877/9adcf0ad2e2ed3c/output.txt

Total script time: 18.09 mins

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

Image differences available at: http://107.22.172.223:8877/9adcf0ad2e2ed3c/reftest-analyzer.html#web=eq.log

@fkaelberer
Copy link
Contributor

If adler32 speed makes a difference for overall rendering time, then we could also skip the modulo operation, if MAX_LENGTH_TO_CACHE is not greater than 5552 according to the German Wikipedia article:

var a = 1;
var b = 0;
for (i = 0, ii = imageBytes.length; i < ii; ++i) {
  // no modulo required in the loop if imageBytes.length < 5552
  a += imageBytes[i] & 0xff; 
  b += a;
}
adler32 = ((b % 65521) << 16) | (a % 65521);

(Quick sanity check: a <= 255 * MAX_LENGTH ==> b <= MAX_LENGTH * MAX_LENGTH * 255 ==> no overflow if MAX_LENGTH <= 1000, so it does not matter if we compute % 65521 every round or only once in the end.)

@CodingFabian
Copy link
Contributor Author

well it has an impact. i will measure the difference and update the PR, @fkaelberer

Its about twice as fast. Great suggestion. Thanks.

As described in mozilla#5444, the evaluator will perform identity checking of
paintImageMaskXObjects to decide if it can use
paintImageMaskXObjectRepeat instead of paintImageMaskXObjectGroup.

This can only ever work if the entry is a cache hit. However the
previous caching implementation was doing a lazy caching, which would
only consider a image cache worthy if it is repeated.
Only then the repeated instance would be cached.
As a result of this the sequence of identical images A1 A2 A3 A4 would
be seen as A1 A2 A2 A2 by the evaluator, which prevents using the
"repeat" optimization. Also only the last encountered image is cached,
so A1 B1 A2 B2, would stay A1 B1 A2 B2.

The new implementation drops the "lazy" init of the cache. The threshold
for enabling an image to be cached is rather small, so the potential waste
in storage and adler32 calculation is rather low. It also caches any
eligible image by its adler32.

The two example from above would now be A1 A1 A1 A1 and A1 B1 A1 B1
which not only saves temporary storage, but also prevents computing
identical masks over and over again (which is the main performance impact
of mozilla#2618)
@yurydelendik
Copy link
Contributor

/botio test

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

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

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

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

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

Live output at: http://107.22.172.223:8877/96be496c0b2908b/output.txt

@pdfjsbot
Copy link

From: Bot.io (Windows)


Failed

Full output at http://107.22.172.223:8877/96be496c0b2908b/output.txt

Total script time: 17.13 mins

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

Image differences available at: http://107.22.172.223:8877/96be496c0b2908b/reftest-analyzer.html#web=eq.log

@pdfjsbot
Copy link

From: Bot.io (Linux)


Failed

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

Total script time: 22.51 mins

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

Image differences available at: http://107.21.233.14:8877/e6c84d6e7269dc1/reftest-analyzer.html#web=eq.log

@yurydelendik
Copy link
Contributor

/botio makeref

Thank you for the patch

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

Command cmd_makeref from @yurydelendik received. Current queue size: 0

Live output at: http://107.22.172.223:8877/7d2734ade5d8cf4/output.txt

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

Command cmd_makeref from @yurydelendik received. Current queue size: 0

Live output at: http://107.21.233.14:8877/4ce79fafcef6541/output.txt

yurydelendik added a commit that referenced this pull request Dec 15, 2014
Fixes caching of inline images during parsing.
@yurydelendik yurydelendik merged commit f5df30f into mozilla:master Dec 15, 2014
@pdfjsbot
Copy link

From: Bot.io (Windows)


Success

Full output at http://107.22.172.223:8877/7d2734ade5d8cf4/output.txt

Total script time: 17.02 mins

  • Lint: Passed
  • Make references: Passed
  • Check references: Passed

@pdfjsbot
Copy link

From: Bot.io (Linux)


Success

Full output at http://107.21.233.14:8877/4ce79fafcef6541/output.txt

Total script time: 22.14 mins

  • Lint: Passed
  • Make references: Passed
  • Check references: Passed

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.

5 participants