这是我用NodeJS做的一个网络健康监测项目。它每秒钟点击谷歌,并将结果(真/假)与日期一起存储在数据库(MongoDB)中。我已经收集了足够的数据,我想代表过去一周的数据。
我创建了一个2x2数组,每个数组由7天和24小时组成。我翻阅每一张唱片,并把它映射到一周中适当的一天和一小时。我给了那个小时一点分数:如果是真+1,如果是假-5。它创造了这样一个小矩阵:
[
[2015, 1724, 1733, 1679, ...
[1818, 1909, 1614, 1829, ...
[1632, 1778, 1726, 1657, ...
...
]唯一的问题是计算需要10-15秒和大量的CPU才能通过仅3天的200 k记录。
这里还有改进的余地吗?
days = days || 3;
var counter = 0
this.find({
date: {
// Date greater than (Now - X days)
$gt: new Date(Date.now() - days * 24 * 3600 * 1000),
},
}, function(err, datums) {
var week = new Array(days);
for (var i = 0; i < week.length; i++)
week[i] = new Array(24);
// Empty Week Matrix (7x24)
datums.forEach(function(data) {
counter++;
var date1 = data.date;
var date2 = new Date();
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
//stackoverflow.com/q/3224834/1266650
var day = days - diffDays;
if (day < 0) return;
var hour = data.date.getHours();
if (!week[day][hour]) week[day][hour] = 0;
if (data.isNetAlive)
week[day][hour]++;
else
week[day][hour] -= 5;
});
console.debug(week);
console.debug(counter, 'records');
});发布于 2015-05-28 04:36:22
您可能希望将1000、3600、24移到“常量”,以便正确地描述它们。类似于:
var HOURS_A_DAY = 24;
var MILLISECONDS_A_SECOND = 1000;
var SECONDS_AN_HOUR = 3600;此外,您可以正确地命名变量,以便容易理解它们。timeDiff可能是timeDifference,diffDays可能是daysDifference。
每次迭代创建日期对象的代价都很高。尝试使用毫秒代替操作。使data.date返回date1的毫秒。然后在Date.now()上使用date2。此外,如果可能的话,避免执行getTime()和getHours()。试着手工计算它们。
下一个,Math.abs可以使用按位操作来完成。。Math.ceil也可以这样做,看看互联网就知道了。下面是一个按位排列的Math.abs的例子,其中n是要绝对化的数字。
return (n < 0) ? (~n + 1) : nBitwise并不是所有数学性能问题的解决方案,它高度依赖于JS引擎的运行。一些按位操作比高级别操作更快,而另一些则相反。这在很大程度上取决于组合,所以试着检查哪一个适合你。
if (!week[day][hour]) week[day][hour] = 0;属性访问和条件评估可能代价高昂。将其移到构建矩阵的for-循环中。这与数据处理无关。它只是将数组中的一个洞初始化为0。
最后,为了获得更漂亮的代码,让我们减少所有的冗馀和更一致的外观。
week[day][hour] += data.isNetAlive ? 1 : -5;https://codereview.stackexchange.com/questions/91792
复制相似问题