This example shows how to change the performance profile when creating
a 51Degrees device detection engine.
It also includes a simple method of benchmarking the engine that
can illustrate the performance differences.
Note that benchmarking is a complex area and this is not a sophisticated
solution. It is simply intended to demonstrate the approximate, relative
performance of the pre-configured profiles.
This example requires a local data file. The free 'Lite' data file can be acquired by
pulling the git submodules under this repository (run `git submodule update --recursive`)
or from the device-detection-data
GitHub repository.
The Lite data file is only used for illustration, and has limited accuracy and capabilities.
Find out about the more capable data files that are available on our
pricing page
This example require module 'n-readlines' to operate. Please install the module before running the example, by using the following command:
const events = require('events');
const path = require('path');
const LineReader = require('n-readlines');
require((process.env.directory || __dirname) +
'/../../../deviceDetectionOnPremisePipelineBuilder');
const LITE_V_4_1_HASH = '51Degrees-LiteV4.1.hash';
const UA_CSV = '20000 User Agents.csv';
const sliceLen = process.env.JEST_WORKER_ID === undefined ? 2 : process.argv.length;
const args = process.argv.slice(sliceLen);
const datafile = args.length > 0 ? args[0] :
ExampleUtils.
findFile(LITE_V_4_1_HASH);
const uafile = args.length > 1 ? args[1] :
ExampleUtils.findFile(UA_CSV);
const fs = require('fs');
if (!fs.existsSync(datafile)) {
console.error('Failed to find a device detection ' +
'data file. Make sure the device-detection-data ' +
'submodule has been updated by running ' +
'`git submodule update --recursive`.');
throw ("No data file at '" + datafile + "'");
}
if (!fs.existsSync(uafile)) {
console.error('Failed to find a User-Agents ' +
'file. Make sure the device-detection-data ' +
'submodule has been updated by running ' +
'`git submodule update --recursive`.');
throw ("No User-Agents file at '" + datafile + "'");
}
const secToNanoSec = 1e9;
const msecToNanoSec = 1e6;
let userAgentsProcessed = 0;
let isMobileTrue = 0;
let isMobileFalse = 0;
let isMobileUnknown = 0;
let userAgentsCount = 0;
let startTime, diffTime, calibrationTime, actualTime;
const eventEmitter = new events.EventEmitter();
eventEmitter.on('FinishProcessing', (calibration) => {
diffTime = process.hrtime(startTime);
if (calibration) {
calibrationTime = diffTime[0] * secToNanoSec + diffTime[1];
console.log('Processing');
run(function (userAgent) {
processUA(userAgent, false);
});
} else {
actualTime = diffTime[0] * secToNanoSec + diffTime[1];
console.log(
'Average ' +
`${(userAgentsCount / (actualTime - calibrationTime)) * secToNanoSec} ` +
'detections per second per thread.');
console.log(
'Average ' +
`${((actualTime - calibrationTime) / msecToNanoSec) / userAgentsCount} ` +
'ms per User-Agent.');
console.log(`ismobile = true : ${isMobileTrue}`);
console.log(`ismobile = false : ${isMobileFalse}`);
console.log(`ismobile = unknown : ${isMobileUnknown}`);
}
});
performanceProfile: 'MaxPerformance',
dataFile: datafile,
restrictedProperties: ['ismobile'],
autoUpdate: false,
shareUsage: false,
usePredictiveGraph: false,
usePerformanceGraph: true,
addJavaScriptBuilder: false
}).build();
pipeline.on('error', console.error);
const progressBar = '========================================';
const reportProgress = function (uaProcessed) {
const bars = Math.round((uaProcessed / userAgentsCount) * progressBar.length);
process.stdout.write(progressBar.substring(0, bars) +
(uaProcessed === userAgentsCount ? '\n' : '\r'));
};
const processUA = async function (userAgent, calibration) {
if (calibration) {
isMobileFalse++;
} else {
const flowData = pipeline.createFlowData();
flowData.evidence.add('header.user-agent', userAgent);
await flowData.process();
const ismobile = flowData.device.ismobile;
if (ismobile.hasValue) {
if (ismobile.value) {
isMobileTrue++;
} else {
isMobileFalse++;
}
} else {
isMobileUnknown++;
}
}
reportProgress(++userAgentsProcessed);
if (userAgentsProcessed === userAgentsCount) {
eventEmitter.emit('FinishProcessing', calibration);
}
};
const run = function (callback) {
const liner = new LineReader(uafile);
let line;
userAgentsProcessed = 0;
startTime = process.hrtime();
line = liner.next();
while (line) {
callback(line.toString('utf8').replace(/\r?\n|\r/g, ''));
line = liner.next();
}
};
run(function () {
userAgentsCount++;
});
console.log('Processing ' + userAgentsCount + ' User-Agents from ' + uafile);
console.log('Calibrating');
run(function (userAgent) {
processUA(userAgent, true);
});