Skip to content

Commit

Permalink
performance: implement caching for roundDecimal() and prevent unneces…
Browse files Browse the repository at this point in the history
…sary recalculations
  • Loading branch information
Connum authored and yne committed Nov 20, 2023
1 parent 2dbaf7a commit a5d48a9
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,25 @@ function Path() {
this.strokeWidth = 1;
}

const decimalRoundingCache = {};

function roundDecimal(float, places) {
return +(Math.round(float + 'e+' + places) + 'e-' + places);
const integerPart = Math.floor(float);
const decimalPart = float - integerPart;

if (!decimalRoundingCache[places]) {
decimalRoundingCache[places] = {};
}

if (decimalRoundingCache[places][decimalPart] !== undefined) {
const roundedDecimalPart = decimalRoundingCache[places][decimalPart];
return integerPart + roundedDecimalPart;
}

const roundedDecimalPart = +(Math.round(decimalPart + 'e+' + places) + 'e-' + places);
decimalRoundingCache[places][decimalPart] = roundedDecimalPart;

return integerPart + roundedDecimalPart;
}

function optimizeCommands(commands) {
Expand Down Expand Up @@ -525,10 +542,11 @@ Path.prototype.toPathData = function(options) {
options = createSVGOutputOptions(options);

function floatToString(v) {
if (Math.round(v) === roundDecimal(v, options.decimalPlaces)) {
return '' + roundDecimal(v, options.decimalPlaces);
const rounded = roundDecimal(v, options.decimalPlaces);
if (Math.round(v) === rounded) {
return '' + rounded;
} else {
return roundDecimal(v, options.decimalPlaces).toFixed(options.decimalPlaces);
return rounded.toFixed(options.decimalPlaces);
}
}

Expand Down

0 comments on commit a5d48a9

Please sign in to comment.