Optimize CMap.prototype.forEach().

This change avoids the element stringification caused by for..in for the
vast majority of CMaps.

When loading the PDF from issue #4580, this change reduces peak RSS from ~650
to ~600 MiB, and improves overall speed by ~20%, from 902 ms to 713 ms.  Other
CMap-heavy documents will also see improvements.
This commit is contained in:
Nicholas Nethercote 2014-07-29 20:33:43 -07:00
parent b86daed29d
commit 28687bca75

View File

@ -242,9 +242,24 @@ var CMap = (function CMapClosure() {
},
forEach: function(callback) {
// Most maps have fewer than 65536 entries, and for those we use normal
// array iteration. But really sparse tables are possible -- e.g. with
// indices in the *billions*. For such tables we use for..in, which isn't
// ideal because it stringifies the indices for all present elements, but
// it does avoid iterating over every undefined entry.
var map = this._map;
for (var key in this._map) {
callback(key, map[key]);
var length = map.length;
var i;
if (length <= 0x10000) {
for (i = 0; i < length; i++) {
if (map[i] !== undefined) {
callback(i, map[i]);
}
}
} else {
for (i in this._map) {
callback(i, map[i]);
}
}
},