Skip to content

Instantly share code, notes, and snippets.

@mrtcmn
Created August 1, 2023 14:08
Show Gist options
  • Save mrtcmn/6f8301a41c26cffaaccbf7ed078c7221 to your computer and use it in GitHub Desktop.
Save mrtcmn/6f8301a41c26cffaaccbf7ed078c7221 to your computer and use it in GitHub Desktop.
Brotli compression params compare
const zlib = require('zlib');
const fs = require('fs');
const { performance } = require('perf_hooks');
const filePath = './output.fixture.json'; // Change this to your file
const outputPath = './compressed.br';
// Weight for time and size in the calculation. Must be between 0 and 1.
const timeWeight = 0.5; // weight for time
const sizeWeight = 1 - timeWeight; // weight for size
// Range of brotli options to test
const brotliParams = {
brotliQuality: Array.from({length: 12}, (_, i) => i), // 0-11
brotliMode: [0, 1, 2], // 0=generic, 1=text, 2=font
};
const testCompress = async (params) => {
const start = performance.now();
const compressor = zlib.createBrotliCompress(params);
const readStream = fs.createReadStream(filePath);
const writeStream = fs.createWriteStream(outputPath);
readStream.pipe(compressor).pipe(writeStream);
return new Promise((resolve) => {
writeStream.on('finish', () => {
const end = performance.now();
const timeTaken = end - start;
const fileSize = fs.statSync(outputPath).size; // Size in bytes
resolve({ timeTaken, fileSize });
});
});
};
const findBestConfiguration = async () => {
let bestScore = Infinity;
let bestConfig = null;
let maxTime = -Infinity, minTime = Infinity;
let maxSize = -Infinity, minSize = Infinity;
const results = [];
for (const quality of brotliParams.brotliQuality) {
for (const mode of brotliParams.brotliMode) {
const params = {
params: {
[zlib.constants.BROTLI_PARAM_MODE]: mode,
[zlib.constants.BROTLI_PARAM_QUALITY]: quality,
}
};
const result = await testCompress(params);
results.push({ params, result });
if (result.timeTaken > maxTime) maxTime = result.timeTaken;
if (result.timeTaken < minTime) minTime = result.timeTaken;
if (result.fileSize > maxSize) maxSize = result.fileSize;
if (result.fileSize < minSize) minSize = result.fileSize;
}
}
for (const { params, result } of results) {
// Normalize time and size to range [0, 1]
const normalizedTime = (result.timeTaken - minTime) / (maxTime - minTime);
const normalizedSize = (result.fileSize - minSize) / (maxSize - minSize);
// Calculate weighted sum
const score = timeWeight * normalizedTime + sizeWeight * normalizedSize;
console.log(`Configuration: ${JSON.stringify(params)}, Time: ${result.timeTaken}ms, Size: ${result.fileSize} bytes, Score: ${score}`);
if (score < bestScore) {
bestScore = score;
bestConfig = params;
}
}
console.log('Best config:', bestConfig);
};
findBestConfiguration();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment