Json 到 node.js 中的 csv
Posted
技术标签:
【中文标题】Json 到 node.js 中的 csv【英文标题】:Json to csv in node.js 【发布时间】:2015-02-13 10:10:46 【问题描述】:我正在尝试在 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 ('');
,
平均运行 1Lac 行时,它从未恢复到甚至记录时间。我不得不手动终止该进程。
有人可以提出更好的替代方案吗?
【问题讨论】:
旁注:为什么你的函数接受cb
参数,却直接返回结果?此外,您是否检查过是否实际生成了行(例如,forEach()
内的调试输出?
对不起。 cb 是多余的,应该被删除。
是的,行已生成,但占用了太多内存和 cpu。有什么有效的内存解决方案吗?
【参考方案1】:
在回答这个问题之前:假设您的代码正在运行,这个问题属于https://codereview.stackexchange.com/。
至于你的问题:
像forEach()
这样的新数组访问函数虽然在编码时相当舒适,但通常性能不佳。一个简单的for
循环是性能关键情况下的更好选择。
在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 不必存储在内存中。
Fiddle to play around with the functions原名和你一样,新的名字后缀2
。
jsPerf.com comparison
【讨论】:
感谢您的宝贵意见,我还不知道 codereview.stackexchange。我将尝试建议的更改并进行更新。 @Hitesh 有用于生成 CSV 的库顺便说一句:github.com/wdavidw/node-csv 我也一定会尝试的。实际上我面临的问题是,在创建这个 csv 之前,除了内存中的整个数据之外,我还有一个巨大的堆栈调用。在创建 csv 时,整个设置内存不足。现在我正在考虑将这个内存计算一起移动到磁盘上。对此有何建议? @Hitesh 在不了解太多细节的情况下很难提出建议。为了减少内存消耗,您可以使用管道:从一个文件中读取(例如,逐行),处理它并立即写入输出文件。这样,在任何时间点,您的内存中都只有一行数据。但如果该方法可行,则取决于您的数据和计算... 我正在尝试几乎相同的路径,唯一的区别是源作为数据库而不是文件。感谢您的意见。以上是关于Json 到 node.js 中的 csv的主要内容,如果未能解决你的问题,请参考以下文章
使用 Node.js 对 JSON 中的字符串大小有限制吗?
如何使用 node.js 将 EXCEL 文件数据读取到 json
Node.js 中 JSON 对象中的 JSON 对象 [关闭]