Skip to content

Commit

Permalink
Performance fixes (#5134)
Browse files Browse the repository at this point in the history
* Further fixes to profile data fetches, change the client to not create excessive amount of date objects

* Sort entries once on load and then rely on the sorting to find out the largest and smallest value

* Make the renderer reuse Date objects instead of instantiating a huge amount of dates all the time
  • Loading branch information
sulkaharo authored Oct 22, 2019
1 parent e10d483 commit 2d07c54
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 33 deletions.
20 changes: 15 additions & 5 deletions lib/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ client.load = function load (serverSettings, callback) {
, urgentAlarmSound = 'alarm2.mp3'
, previousNotifyTimestamp;

client.entryToDate = function entryToDate (entry) { return new Date(entry.mills); };
client.entryToDate = function entryToDate (entry) {
if (entry.date) return entry.date;
entry.date = new Date(entry.mills);
return entry.date;
};

client.now = Date.now();
client.ddata = require('../data/ddata')();
Expand Down Expand Up @@ -260,10 +264,12 @@ client.load = function load (serverSettings, callback) {
//client.ctx.bus.uptime( );

client.dataExtent = function dataExtent () {
return client.entries.length > 0 ?
d3.extent(client.entries, client.entryToDate) :
d3.extent([new Date(client.now - times.hours(history).msecs), new Date(client.now)]);
};
if (client.entries.length > 0) {
return[client.entryToDate(client.entries[0]), client.entryToDate(client.entries[client.entries.length-1])];
} else {
return [new Date(client.now - times.hours(history).msecs), new Date(client.now)];
}
};

client.bottomOfPills = function bottomOfPills () {
//the offset's might not exist for some tests
Expand Down Expand Up @@ -1140,6 +1146,10 @@ client.load = function load (serverSettings, callback) {
point.color = 'transparent';
}
});

client.entries.sort(function sorter(a,b) {
return a.mills - b.mills;
});
}

function dataUpdate (received, headless) {
Expand Down
46 changes: 27 additions & 19 deletions lib/client/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ var DEFAULT_FOCUS = times.hours(3).msecs
, TOOLTIP_WIDTH = 150 //min-width + padding
;

const zeroDate = new Date(0);

function init (client, d3) {

var renderer = {};

var utils = client.utils;
var translate = client.translate;

function getOrAddDate(entry) {
if (entry.date) return entry.date;
entry.date = new Date(entry.mills);
return entry.date;
}

//chart isn't created till the client gets data, so can grab the var at init
function chart () {
return client.chart;
Expand Down Expand Up @@ -94,12 +102,12 @@ function init (client, d3) {
sel.attr('cx', function(d) {
if (!d) {
console.error('Bad data', d);
return chart().xScale(new Date(0));
return chart().xScale(zeroDate);
} else if (!d.mills) {
console.error('Bad data, no mills', d);
return chart().xScale(new Date(0));
return chart().xScale(zeroDate);
} else {
return chart().xScale(new Date(d.mills));
return chart().xScale(getOrAddDate(d));
}
})
.attr('cy', function(d) {
Expand Down Expand Up @@ -169,7 +177,7 @@ function init (client, d3) {
(d.type === 'forecast' && d.forecastType ? '<br/><strong>' + translate('Forecast Type') + ': </strong>' + d.forecastType : '') +
(rawbgInfo.value ? '<br/><strong>' + translate('Raw BG') + ':</strong> ' + rawbgInfo.value : '') +
(rawbgInfo.noise ? '<br/><strong>' + translate('Noise') + ':</strong> ' + rawbgInfo.noise : '') +
'<br/><strong>' + translate('Time') + ':</strong> ' + client.formatTime(new Date(d.mills)))
'<br/><strong>' + translate('Time') + ':</strong> ' + client.formatTime(getOrAddDate(d)))
.style('left', tooltipLeft())
.style('top', (d3.event.pageY + 15) + 'px');
}
Expand Down Expand Up @@ -229,7 +237,7 @@ function init (client, d3) {
}
}

return '<strong>' + translate('Time') + ':</strong> ' + client.formatTime(new Date(d.mills)) + '<br/>' +
return '<strong>' + translate('Time') + ':</strong> ' + client.formatTime(getOrAddDate(d)) + '<br/>' +
(d.eventType ? '<strong>' + translate('Treatment type') + ':</strong> ' + translate(client.careportal.resolveEventName(d.eventType)) + '<br/>' : '') +
(d.reason ? '<strong>' + translate('Reason') + ':</strong> ' + translate(d.reason) + '<br/>' : '') +
(d.glucose ? '<strong>' + translate('BG') + ':</strong> ' + d.glucose + (d.glucoseType ? ' (' + translate(d.glucoseType) + ')' : '') + '<br/>' : '') +
Expand All @@ -243,7 +251,7 @@ function init (client, d3) {
}

function announcementTooltip (d) {
return '<strong>' + translate('Time') + ':</strong> ' + client.formatTime(new Date(d.mills)) + '<br/>' +
return '<strong>' + translate('Time') + ':</strong> ' + client.formatTime(getOrAddDate(d)) + '<br/>' +
(d.eventType ? '<strong>' + translate('Announcement') + '</strong><br/>' : '') +
(d.notes && d.notes.length > 1 ? '<strong>' + translate('Message') + ':</strong> ' + d.notes + '<br/>' : '') +
(d.enteredBy ? '<strong>' + translate('Entered By') + ':</strong> ' + d.enteredBy + '<br/>' : '');
Expand Down Expand Up @@ -272,7 +280,7 @@ function init (client, d3) {
function updateTreatCircles (sel) {

sel.attr('cx', function(d) {
return chart().xScale(new Date(d.mills));
return chart().xScale(getOrAddDate(d));
})
.attr('cy', function(d) {
return chart().yScale(client.sbx.scaleEntry(d));
Expand Down Expand Up @@ -366,26 +374,26 @@ function init (client, d3) {
if (d.eventType === 'Temporary Target') {
top = d.targetTop === d.targetBottom ? d.targetTop + rectHeight(d) : d.targetTop;
}
return 'translate(' + chart().xScale(new Date(d.mills)) + ',' + chart().yScale(utils.scaleMgdl(top)) + ')';
return 'translate(' + chart().xScale(getOrAddDate(d)) + ',' + chart().yScale(utils.scaleMgdl(top)) + ')';
}

function treatmentRectWidth (d) {
if (d.durationType === "indefinite") {
return chart().xScale(chart().xScale.domain()[1].getTime()) - chart().xScale(new Date(d.mills));
return chart().xScale(chart().xScale.domain()[1].getTime()) - chart().xScale(getOrAddDate(d));
} else {
return chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills));
return chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(getOrAddDate(d));
}
}

function treatmentTextTransform (d) {
if (d.durationType === "indefinite") {
var offset = 0;
if (chart().xScale(new Date(d.mills)) < chart().xScale(chart().xScale.domain()[0].getTime())) {
offset = chart().xScale(nowDate) - chart().xScale(new Date(d.mills));
if (chart().xScale(getOrAddDate(d)) < chart().xScale(chart().xScale.domain()[0].getTime())) {
offset = chart().xScale(nowDate) - chart().xScale(getOrAddDate(d));
}
return 'translate(' + offset + ',' + 10 + ')';
} else {
return 'translate(' + (chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills))) / 2 + ',' + 10 + ')';
return 'translate(' + (chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(getOrAddDate(d))) / 2 + ',' + 10 + ')';
}
}

Expand Down Expand Up @@ -454,7 +462,7 @@ function init (client, d3) {

function prepareContextCircles (sel) {
var badData = [];
sel.attr('cx', function(d) { return chart().xScale2(new Date(d.mills)); })
sel.attr('cx', function(d) { return chart().xScale2(getOrAddDate(d)); })
.attr('cy', function(d) {
var scaled = client.sbx.scaleEntry(d);
if (isNaN(scaled)) {
Expand Down Expand Up @@ -620,7 +628,7 @@ function init (client, d3) {
}

client.tooltip.style('opacity', .9);
client.tooltip.html('<strong>' + translate('Time') + ':</strong> ' + client.formatTime(new Date(treatment.mills)) + '<br/>' + '<strong>' + translate('Treatment type') + ':</strong> ' + translate(client.careportal.resolveEventName(treatment.eventType)) + '<br/>' +
client.tooltip.html('<strong>' + translate('Time') + ':</strong> ' + client.formatTime(getOrAddDate(treatment)) + '<br/>' + '<strong>' + translate('Treatment type') + ':</strong> ' + translate(client.careportal.resolveEventName(treatment.eventType)) + '<br/>' +
(treatment.carbs ? '<strong>' + translate('Carbs') + ':</strong> ' + treatment.carbs + '<br/>' : '') +
(treatment.protein ? '<strong>' + translate('Protein') + ':</strong> ' + treatment.protein + '<br/>' : '') +
(treatment.fat ? '<strong>' + translate('Fat') + ':</strong> ' + treatment.fat + '<br/>' : '') +
Expand Down Expand Up @@ -768,7 +776,7 @@ function init (client, d3) {
chart().drag.append('line')
.attr('class', 'arrow')
.attr('marker-end', 'url(#arrow)')
.attr('x1', chart().xScale(new Date(treatment.mills)))
.attr('x1', chart().xScale(getOrAddDate(treatment)))
.attr('y1', chart().yScale(client.sbx.scaleEntry(treatment)))
.attr('x2', x)
.attr('y2', y)
Expand Down Expand Up @@ -912,7 +920,7 @@ function init (client, d3) {
.enter()
.append('g')
.attr('class', 'draggable-treatment')
.attr('transform', 'translate(' + chart().xScale(new Date(treatment.mills)) + ', ' + chart().yScale(client.sbx.scaleEntry(treatment)) + ')')
.attr('transform', 'translate(' + chart().xScale(getOrAddDate(treatment)) + ', ' + chart().yScale(client.sbx.scaleEntry(treatment)) + ')')
.on('mouseover', treatmentTooltip)
.on('mouseout', hideTooltip);
if (client.editMode) {
Expand Down Expand Up @@ -994,7 +1002,7 @@ function init (client, d3) {
//when the tests are run window isn't available
var innerWidth = window && window.innerWidth || -1;
// don't render the treatment if it's not visible
if (Math.abs(chart().xScale(new Date(treatment.mills))) > innerWidth) {
if (Math.abs(chart().xScale(getOrAddDate(treatment))) > innerWidth) {
return;
}

Expand Down Expand Up @@ -1159,7 +1167,7 @@ function init (client, d3) {
}

function profileTooltip (d) {
return '<strong>' + translate('Time') + ':</strong> ' + client.formatTime(new Date(d.mills)) + '<br/>' +
return '<strong>' + translate('Time') + ':</strong> ' + client.formatTime(getOrAddDate(d)) + '<br/>' +
(d.eventType ? '<strong>' + translate('Treatment type') + ':</strong> ' + translate(client.careportal.resolveEventName(d.eventType)) + '<br/>' : '') +
(d.endprofile ? '<strong>' + translate('End of profile') + ':</strong> ' + d.endprofile + '<br/>' : '') +
(d.profile ? '<strong>' + translate('Profile') + ':</strong> ' + d.profile + '<br/>' : '') +
Expand Down
31 changes: 22 additions & 9 deletions lib/profilefunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ var c = require('memory-cache');
var times = require('./times');
var crypto = require('crypto');

var cacheTTL = 600;

var cacheTTL = 5000;
var prevBasalTreatment = null;
var cache = new c.Cache();

function init (profileData) {

var profile = {};
var cache = new c.Cache();

profile.loadData = function loadData (profileData) {
if (profileData && profileData.length) {
Expand Down Expand Up @@ -139,10 +138,22 @@ function init (profileData) {
};

profile.getCurrentProfile = function getCurrentProfile (time, spec_profile) {
time = time || new Date().getTime();

time = time || Date.now();
var minuteTime = Math.round(time / 60000) * 60000;
var cacheKey = ("profile" + minuteTime + spec_profile);
var returnValue = cache.get(cacheKey);

if (returnValue) {
return returnValue;
}

var data = profile.hasData() ? profile.data[0] : null;
var timeprofile = spec_profile || profile.activeProfileToTime(time);
return data && data.store[timeprofile] ? data.store[timeprofile] : {};
returnValue = data && data.store[timeprofile] ? data.store[timeprofile] : {};

cache.put(cacheKey, returnValue, cacheTTL);
return returnValue;
};

profile.getUnits = function getUnits (spec_profile) {
Expand Down Expand Up @@ -223,9 +234,10 @@ function init (profileData) {
};

profile.activeProfileTreatmentToTime = function activeProfileTreatmentToTime (time) {
var cacheKey = 'profile' + time + profile.profiletreatments_hash;
//var returnValue = profile.timeValueCache[cacheKey];
var returnValue;

var minuteTime = Math.round(time / 60000) * 60000;
var cacheKey = 'profile' + minuteTime + profile.profiletreatments_hash;
var returnValue = cache.get(cacheKey);

if (returnValue) {
return returnValue;
Expand Down Expand Up @@ -312,7 +324,8 @@ function init (profileData) {

profile.getTempBasal = function getTempBasal (time, spec_profile) {

var cacheKey = 'basal' + time + profile.tempbasaltreatments_hash + profile.combobolustreatments_hash + profile.profiletreatments_hash + spec_profile;
var minuteTime = Math.round(time / 60000) * 60000;
var cacheKey = 'basal' + minuteTime + profile.tempbasaltreatments_hash + profile.combobolustreatments_hash + profile.profiletreatments_hash + spec_profile;
var returnValue = cache.get(cacheKey);

if (returnValue) {
Expand Down

0 comments on commit 2d07c54

Please sign in to comment.