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. Free data files can be acquired by
pulling the submodules under this repository or from the
device-detection-data
GitHub repository.
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 lineReader = require('n-readlines');
require((process.env.directory || __dirname) +
'/../../deviceDetectionOnPremisePipelineBuilder');
const datafile = (process.env.directory || __dirname) +
'/../../device-detection-cxx/device-detection-data/51Degrees-LiteV4.1.hash';
const uafile = (process.env.directory || __dirname) +
'/../../device-detection-cxx/device-detection-data/20000 User Agents.csv';
const fs = require('fs');
if (!fs.existsSync(datafile)) {
console.error('The datafile required by this example is not present. ' +
'Please ensure that the \'device-detection-data\' submodule has been ' +
'fetched.');
throw ("No data file at '" + datafile + "'");
}
if (!fs.existsSync(uafile)) {
console.error('The User-Agents file required by this example is not ' +
'present. Please ensure that the \'device-detection-data\' submodule ' +
'has been fetched.');
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) {
let 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();
while(line = liner.next()) {
callback(line.toString('utf8').replace(/\r?\n|\r/g, ""));
}
}
run(function () {
userAgentsCount++;
})
console.log('Processing ' + userAgentsCount + ' User-Agents from ' + uafile);
console.log('Calibrating');
run(function (userAgent) {
processUA(userAgent, true);
})