我正在尝试将一个巨大的CSV(56595行)解析为JSONArray
,但这需要相当长的时间。这就是我的代码的样子,完成需要大约17秒。我根据其中一个列限制了我的结果,但代码仍然必须通过整个CSV文件。
有更有效的方法吗?我排除了catch
,finally
和throws
以节省空间。
代码
...
BufferedReader reader = null;
String line = "";
//jArray is retrieved by an ajax call and used in a graph
JSONArray jArray = new JSONArray();
HttpClient httpClient = new DefaultHttpClient();
try {
//url = CSV file
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet);
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 200) {
try {
reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while (((line = reader.readLine()) != null)) {
JSONObject json = new JSONObject();
String[] row = line.split(",");
//skips first three rows
if(row.length > 2){
//map = 4011
if(row[1].equals(map)) {
json.put("col0", row[0]);
json.put("col1", row[1]);
json.put("col2", row[2]);
json.put("col3", row[3]);
json.put("col4", row[4]);
json.put("col5", row[5]);
json.put("col6", row[6]);
jArray.put(json);
}
}
return jArray;
}
...
答案 0 :(得分:0)
不幸的是,主要的延迟可能是从HTTP下载文件,因此您的所有机会都将依赖于优化代码。因此,根据您提供的信息,我可以建议一些增强功能来优化您的算法:
以流媒体模式处理输入文件是一个好主意,用BufferedReader
逐行阅读。通常,设置显式缓冲区大小(BufferedReader的默认大小为8Kb)是一个好习惯,但作为网络连接的源,我怀疑在这种情况下它会更好。无论如何,你应该试试16Kb,例如。
由于输出项目的数量非常少(49,你说),将它存储在一个数组中并不重要(对于更高的数量,我建议你选择另一个集合,比如LinkedList),但对于预先调整大小它的估计大小总是有用的。在JSONArray中,我认为在方法的开头将null
项放在位置100(例如)就足够了。
我认为最重要的是行line.split(",")
,因为这使得程序遍历整行,将其内容逐字符复制到数组中,最糟糕的是所有,最终仅在0.1%的情况下使用。
可能还有一个更糟糕的缺点:仅使用逗号分割可能不是正确解析JSON行的好方法。我的意思是:您确定 json值不能包含逗号作为用户数据的一部分吗?
好吧,为了解决这个问题,我建议你编写自己的json自定义解析算法,这可能有点难,但值得努力。您必须对检测到第二个值的状态机进行编码,如果该键与过滤值(“4011”)一致,则继续解析该行的其余部分。通过这种方式,您将节省大量的时间和内存。