Javascript和集合
在javascript/NodeJs中有3个列表/数组Javascript和集合,javascript,arrays,node.js,performance,indexing,Javascript,Arrays,Node.js,Performance,Indexing,在javascript/NodeJs中有3个列表/数组 数组包含1.000.000个数据项 数组包含100.000个数据项 数组包含50000个数据项 每个数据项都是一个具有两个属性的对象,如日期和价格。 数组2和3中的所有项都是数组1中项的子集/子列表 我的问题:对于数组1中的每个项目,如何以最快的方式将数组1中每个项目的所有日期与数组2和数组3中的所有日期进行匹配 我已经习惯了.NET/C#-其中类似“contains(item)”的内容很好。。。现在在NodeJS中,我使用3作为循环-这是
array 1: 1,2,3,4,5,6,7,8,10
array 2: 2,3,5,7,9
array 3: 1,4,5,10
输出(写入文件):
我会尝试首先按键属性(Date,afaiu)对所有数组进行排序(如果尚未排序),然后在第一个数组上使用一个for循环,并在另外两个数组中使用游标,这将仅在当前项写入输出时移动到下一项。这样就不会在整个数组中进行任何“包含”搜索 例如:
var j = 0;
var k = 0;
for( var i = 0; i < array1.length; ++i ) {
var out1 = array1[i].date;
var out2 = j < array2.length && array2[j].date == out1 ? array2[j++].value : '';
var out3 = k < array3.length && array3[k].date == out1 ? array3[k++].value : '';
output( out1, out2, out3 );
}
var j=0;
var k=0;
对于(变量i=0;i
这将是一个线性操作,首先对数据进行排序的折衷可能值得,也可能不值得花时间进行排序
这与三重连接差不多,我提供的解决方案是O(N),其中嵌套循环可能是O(N^3),排序的解决方案可能仍然是O(Nlog(N)),只是一个猜测
如果已经对日期进行了排序,则可以对日期进行bucketize或进行某种基数搜索,这样可能会加快排序速度
见:
您还可以使用Promissions来执行此操作,因此它可以异步运行:
var t = {}
// loop through once and create a constant time lookup
arr1.forEach(function(item){t[item.date] = {1: item.price, 2: null, 3:null})
var promiseArray = arr2.map(function(item){
return Promise.resolve(item)
.then(function(item){
if (t[item.date]) t[item.date].2 = item.price})
})
// concat the two promise arrays together
promiseArray.concat(arr3.map(function(item){
return Promise.resolve(item)
.then(function(item){
if (t[item.date]) t[item.date].3 = item.price})
}))
// resolve all the promises
Promise.all(promiseArray)
.then(function(){
// t has results
debugger
})
这是javascript!考虑将数组重构为对象,以便Dead属性将成为一个键,例如: var arr2={'2016-05-13 00:00:01':{prop:'value',prop2:'value'},'2016-05-13 00:00:02':{prop:'value',prop2:'value'},…};
这样,arr2[date]要么返回对象,要么返回未定义的对象。如果你得到一个对象,把它转换成适合输出的字符串;否则写“”或其他任何东西。如果数组被排序,我想JS中最快的数组求交算法是这样的
function intersect(a1, a2)
{
var a1i = 0,
a2i = 0,
isect = [];
while( a1i < a1.length && a2i < a2.length ){
if (a1[a1i].date < a2[a2i].date) a1i++;
else if (a1[a1i].date > a2[a2i].date) a2i++;
else {isect.push(a1i); // they match
a1i++;
a2i++;}
}
return isect;
}
“”;是否有重复的日期?日期是一个
日期对象还是一个字符串?能否包含一个示例对象,其日期和价格可能匹配,也可能不匹配?您使用了多少RAM?在my postgresql db中,日期保存为“带时区的时间戳”。“2014-12-01 05:33:56.761199+00数据项示例:新交易点(日期、价格)-如果日期匹配,则将价格添加到新列表/行中。。。关于记忆,尽可能少。。。2-4-8gb…每个列表中没有重复的日期/项。@PabloDK,数组是否保证提前排序?使用数组而不是对象是否有原因?让我重新表述我的问题:不要使用具有2个属性的小对象,而是将其推到数组中。是否有其他结构/类型的集合在javascript中更快/性能更好(特别是在尽可能快地在数组中查找给定对象方面)?这正是我目前正在做的。。。但我认为javascript中一定有一种更快的方法?是的-所有列表/数组按日期按相同顺序排序…@PabloDK,请检查我刚才添加的示例。你确定你在做那样的事吗?因为您编写了3个for循环,而可以只使用一个。您必须将长度存储在变量中。@Knu,OMG,这只是一个带有2个附加游标的单个for循环的概念,我在手机上键入了它。当然,任何在循环内被反复解析为常量的值,都必须在循环外只计算一次。但是这个优化对问题的作者来说太明显了,所以我决定不让这个例子过于复杂。@JustAndrei-我看到了你的代码循环并遍历了array1…但是我看到的方式是代码-它没有遍历array2或array3?它只需要进行一次比较(var out2=j集群
模块完成的,它需要消息传递。它的好处在于,当处理大量传入请求时,请求或多或少会在每个核心之间实现负载平衡。通过使用承诺编写它,它为单个线程/核心/事件循环提供了在不阻塞的情况下处理其他传入请求的机会。因此,在承诺等待解决的同时,如果有其他请求进来,好处就会显现出来。关于共享内存的答案,请参阅:我认为那里的评论建议ems
,但可能更容易将var t
卸载到redis实例中,并使用分叉承诺访问它。另一种想法是,这对node既有好处也有坏处。我不记得所有的细节…但一旦我
var t = {}
// loop through once and create a constant time lookup
arr1.forEach(function(item){t[item.date] = {1: item.price, 2: null, 3:null})
var promiseArray = arr2.map(function(item){
return Promise.resolve(item)
.then(function(item){
if (t[item.date]) t[item.date].2 = item.price})
})
// concat the two promise arrays together
promiseArray.concat(arr3.map(function(item){
return Promise.resolve(item)
.then(function(item){
if (t[item.date]) t[item.date].3 = item.price})
}))
// resolve all the promises
Promise.all(promiseArray)
.then(function(){
// t has results
debugger
})
function intersect(a1, a2)
{
var a1i = 0,
a2i = 0,
isect = [];
while( a1i < a1.length && a2i < a2.length ){
if (a1[a1i].date < a2[a2i].date) a1i++;
else if (a1[a1i].date > a2[a2i].date) a2i++;
else {isect.push(a1i); // they match
a1i++;
a2i++;}
}
return isect;
}