mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-21 23:58:07 +02:00
Add local caching of "simple" Graphics State (ExtGState) data in PartialEvaluator.getOperatorList
(issue 2813)
This patch will help pathological cases the most, with issue 2813 being a particularily problematic example. While there's only *four* `/ExtGState` resources, there's a total `29062` of `setGState` operators. Even though parsing of a single `/ExtGState` resource is quite fast, having to re-parse them thousands of times does add up quite significantly. For simplicity we'll only cache "simple" `/ExtGState` resource, since e.g. the general `SMask` case cannot be easily cached (without re-factoring other code, which may have undesirable effects on general parsing). By caching "simple" `/ExtGState` resource, we thus improve performance by: - Not having to fetch/validate/parse the same `/ExtGState` data over and over. - Handling of repeated `setGState` operators becomes *synchronous* during the `OperatorList` building, instead of having to defer to the event-loop/microtask-queue since the `/ExtGState` parsing is done asynchronously. --- Obviously I had intended to include (standard) benchmark results with this patch, but for reasons I don't understand the test run-time (even with `master`) of the document in issue 2813 is *a lot* slower than in the development viewer (making normal benchmarking infeasible). However, testing this manually in the development viewer (using `pdfBug=Stats`) shows a *reduction* of `~10 %` in the rendering time of the PDF document in issue 2813.
This commit is contained in:
parent
6c39aff374
commit
90eb579713
3 changed files with 127 additions and 36 deletions
|
@ -242,23 +242,35 @@ describe("evaluator", function () {
|
|||
);
|
||||
});
|
||||
it("should execute if nested commands", function (done) {
|
||||
const gState = new Dict();
|
||||
gState.set("LW", 2);
|
||||
gState.set("CA", 0.5);
|
||||
|
||||
const extGState = new Dict();
|
||||
extGState.set("GS2", gState);
|
||||
|
||||
const resources = new ResourcesMock();
|
||||
resources.ExtGState = extGState;
|
||||
|
||||
var stream = new StringStream("/F2 /GS2 gs 5.711 Tf");
|
||||
runOperatorListCheck(
|
||||
partialEvaluator,
|
||||
stream,
|
||||
new ResourcesMock(),
|
||||
function (result) {
|
||||
expect(result.fnArray.length).toEqual(3);
|
||||
expect(result.fnArray[0]).toEqual(OPS.setGState);
|
||||
expect(result.fnArray[1]).toEqual(OPS.dependency);
|
||||
expect(result.fnArray[2]).toEqual(OPS.setFont);
|
||||
expect(result.argsArray.length).toEqual(3);
|
||||
expect(result.argsArray[0].length).toEqual(1);
|
||||
expect(result.argsArray[1].length).toEqual(1);
|
||||
expect(result.argsArray[2].length).toEqual(2);
|
||||
done();
|
||||
}
|
||||
);
|
||||
runOperatorListCheck(partialEvaluator, stream, resources, function (
|
||||
result
|
||||
) {
|
||||
expect(result.fnArray.length).toEqual(3);
|
||||
expect(result.fnArray[0]).toEqual(OPS.setGState);
|
||||
expect(result.fnArray[1]).toEqual(OPS.dependency);
|
||||
expect(result.fnArray[2]).toEqual(OPS.setFont);
|
||||
expect(result.argsArray.length).toEqual(3);
|
||||
expect(result.argsArray[0]).toEqual([
|
||||
[
|
||||
["LW", 2],
|
||||
["CA", 0.5],
|
||||
],
|
||||
]);
|
||||
expect(result.argsArray[1]).toEqual(["g_font_error"]);
|
||||
expect(result.argsArray[2]).toEqual(["g_font_error", 5.711]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should skip if too few arguments", function (done) {
|
||||
var stream = new StringStream("5 d0");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue