我正在尝试将一个巨大的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;
}
...
不幸的是,主要的延迟可能是从HTTP下载文件,因此您的所有机会都将依赖于优化代码。因此,根据您提供的信息,我可以建议一些增强功能来优化您的算法:
BufferedReader
逐行读取。通常,设置显式缓冲区大小(BufferedReader的默认大小为8Kb)是一个好习惯,但作为网络连接的源,我怀疑在这种情况下它会更好。无论如何,你应该尝试16Kb。null
项放在方法开头的位置100(例如)就足够了。line.split(",")
,因为这使得程序遍历整行,将其内容逐字符复制到数组中,最糟糕的是,最终只在0.1%的情况下使用它。甚至可能存在更糟糕的缺点:仅使用逗号分割可能不是正确解析JSON行的好方法。我的意思是:你确定json值不能包含逗号作为用户数据的一部分吗?
好吧,为了解决这个问题,我建议你编写自己的json自定义解析算法,这可能有点难,但值得付出努力。您必须对检测到第二个值的状态机进行编码,如果该键与过滤值(“4011”)一致,则继续解析该行的其余部分。这样,您将节省大量的时间和内存。