这是一个创建于 2453 天前的主题,其中的信息可能已经有所发展或是发生改变。
一共两万多行数据,我用二分法发现在读取 15075 行数据的时候就会报栈溢出,但是这行数据并没有什么不同。代码如下:
中间的逻辑判断部分比较复杂?大佬无视就好。主要看我的递归哪里错了?
function getdata(line)
{
i++;
if (typeof line =='string'){//判断是否为字符串
var dataarray = line.split(',');
if (person.hasOwnProperty(dataarray[4]+dataarray[7]) == false){//判断是否字符串已存在,key 为 brand+x
person[dataarray[4]+dataarray[7]] = dataarray;
k ++;
}
else{//如果已存在
if (real_length(String(dataarray)) > real_length(String(person[dataarray[4]+dataarray[7]]))){//比较字符串的非空长度,后者比前者大则替代
l++;
fWriteError.write(person[dataarray[4]+dataarray[7]]+os.EOL)//将淘汰的字符串记录下来
person[dataarray[4]+dataarray[7]] = dataarray;
}
else if(real_length(String(dataarray)) == real_length(String(person[dataarray[4]+dataarray[7]]))){//比较字符串的非空长度,如果两者相等
if (jmz.GetLength(String(dataarray[6])) > jmz.GetLength(String(person[dataarray[4]+dataarray[7]][6])) ){//比较字符串中 addr 字段的字符数
console.log(dataarray[6]);
console.log(person[dataarray[4]+dataarray[7]][6]);
person[dataarray[4]+dataarray[7]] = dataarray;
l++;
}
else{
l++
}
}
else{
l++;
}
}
}
if(i<15705)
{
getdata(dataArrayAll[i])
}
}
getdata(dataArrayAll[0]);
5 条回复 • 2018-02-05 12:36:45 +08:00
|
|
1
okface 2018-01-16 19:39:16 +08:00
不会整理代码。。各位放到格式化工具里看一下吧。。。
|
|
|
2
semut 2018-01-16 19:40:54 +08:00
不懂 js,但是这个排版可以调整下,看着真难受
|
|
|
3
feverzsj 2018-01-16 19:47:59 +08:00
v8 现在应该可以自动去除尾递归的,可能是你的 node 版本太老了,不行就改成迭代好了
|
|
|
4
okface 2018-01-16 20:01:34 +08:00
|
|
|
5
mdluo 2018-02-05 12:36:45 +08:00 1
1. 能用循环做的事情就不要用递归,递归相比循环有相当大的性能差距。
2. node.js 只有特定几个版本有尾递归优化,而且需要 flag 来开启,最新版本是没有的( http://node.green/),函数调用的 Maximum call stack size 就是一个一万多的值。另外,ES6 里的尾递归优化是需要有 return 才可以的。
2. 大文件读取尽量用 Stream,可以指定分块的长度,而且不会一直阻塞 event loop.
3. 如果一定要用递归才能实现的逻辑,通过 setTimeout(func, 0)、setImmediate(func)、或者 process.nextTick(func) 把把递归的深度从 call stack 转移到 task queue.
4. 另外代码优化相关的,能在循环外通过局部变量存起来的值就不用在循环里用函数调用去读取。
|