我正在尝试在 node.js 中将非常大的 json 转换为 csv,但它花费了太多时间,并且在转换时导致 100% cpu 占用。
jsonToCsv: function (data) {
var keys = Object.keys(data[0]);
var csv = [keys.join(",")];
console.time("CSVGeneration");
data.forEach(function (row) {
var line = '';
keys.forEach(function (key) {
if (typeof row[key] === 'string') {
row[key] = "" + file_utils.escapeCsv(row[key]) + "";
}
line += row[key] + ",";
});
csv.push(line);
});
console.timeEnd("CSVGeneration");
csv = csv.join("\n");
return csv;
},
escapeCsv: function (x) {
if (x)
return ('' + x.replace(/"/g, '').replace(/,/g, ' ').replace(/\n/g, " ").replace(/\r/g, " ") + '');
else
return ('');
},
平均运行 1 Lac 行时,它从未恢复到事件日志时间。我不得不手动终止该进程。
有人可以建议一个更好的替代方案吗?
在回答这个问题之前:假设您的代码正常工作,这个问题属于https://codereview.stackexchange.com/ https://codereview.stackexchange.com/ .
至于你的问题:
- 新的数组访问函数,例如
forEach()
虽然编码时相当舒适,但通常性能不太好。一个简单的for
在性能关键的情况下,循环是更好的选择。
- in
escapeCsv()
您应用 4 种不同的正则表达式替换,每种替换仅针对一个字符。将它们合二为一。
- 假设您的数据已经以某种方式结构化,允许进行 Csv 转换(
data
是一个对象数组,每个对象都具有相同的属性),因此无需单独检索每个对象的键。
应用这个,产生以下代码:
function escapeCsv(x) {
if (x) {
return ('' + x).replace( /[",\n\r]/gi, '' );
} else {
return ('');
}
}
function jsonToCsv(data) {
var keys = Object.keys(data[0]),
csv = [keys.join(",")];
var row = new Array( keys.length );
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < keys.length; j++) {
if (typeof data[i][keys[j]] === 'string') {
row[j] = '"' + escapeCsv(data[i][keys[j]]) + '"';
} else {
row[j] = data[i][keys[j]] || '';
}
}
csv.push(row.join(','));
}
return csv.join("\n");
}
根据 jsPerf 的说法,仅此一项就可以将性能提高约 3-5 倍。
如果您生成的 CSV 可以直接流式传输到文件或客户端,则可以进一步改进并减少内存负载,因为 CSV 不必存储在内存中。
摆弄函数 http://jsfiddle.net/j0n9hzs9/原始名称与您的名称相同,新名称带有后缀2
.
jsPerf.com 比较 http://jsperf.com/json2csv
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)