我有一个基本方法,它从硬盘驱动器读取 ~1000 个文件,每个文件有 ~10,000 行。另外,我有一个String
调用数组,userDescription
其中包含用户的所有“描述词”。我创建了一个 HashMap,其数据结构HashMap<String, HashMap<String, Integer>>
对应于HashMap<eachUserDescriptionWords, HashMap<TweetWord, Tweet_Word_Frequency>>
.
该文件组织为:
<User=A>\t<Tweet="tweet...">\n
<User=A>\t<Tweet="tweet2...">\n
<User=B>\t<Tweet="tweet3...">\n
....
我的方法是:
for (File file : tweetList) {
if (file.getName().endsWith(".txt")) {
System.out.println(file.getName());
BufferedReader in;
try {
in = new BufferedReader(new FileReader(file));
String str;
while ((str = in.readLine()) != null) {
// String split[] = str.split("\t");
String split[] = ptnTab.split(str);
String user = ptnEquals.split(split[1])[1];
String tweet = ptnEquals.split(split[2])[1];
// String user = split[1].split("=")[1];
// String tweet = split[2].split("=")[1];
if (tweet.length() == 0)
continue;
if (!prevUser.equals(user)) {
description = userDescription.get(user);
if (description == null)
continue;
if (prevUser.length() > 0 && wordsCount.size() > 0) {
for (String profileWord : description) {
if (wordsCorr.containsKey(profileWord)) {
HashMap<String, Integer> temp = wordsCorr
.get(profileWord);
wordsCorr.put(profileWord,
addValues(wordsCount, temp));
} else {
wordsCorr.put(profileWord, wordsCount);
}
}
}
// wordsCount = new HashMap<String, Integer>();
wordsCount.clear();
}
setTweetWordCount(wordsCount, tweet);
prevUser = user;
}
} catch (IOException e) {
System.err.println("Something went wrong: "
+ e.getMessage());
}
}
}
在这里,该方法setTweetWord
计算单个用户的所有推文的词频。方法是:
private void setTweetWordCount(HashMap<String, Integer> wordsCount,
String tweet) {
ArrayList<String> currTweet = new ArrayList<String>(
Arrays.asList(removeUnwantedStrings(tweet)));
if (currTweet.size() == 0)
return;
for (String word : currTweet) {
try {
if (word.equals("") || word.equals(null))
continue;
} catch (NullPointerException e) {
continue;
}
Integer countWord = wordsCount.get(word);
wordsCount.put(word, (countWord == null) ? 1 : countWord + 1);
}
}
addValues 方法检查是否wordCount
有已经在巨型 HashMap wordsCorr 中的单词。如果是这样,它会增加原始 HashMap 中单词的计数wordsCorr
。
现在,我的问题是无论我做什么程序都很慢。我在我的服务器上运行了这个版本,它有相当好的硬件,但它已经 28 小时了,扫描的文件数量只有 450 左右。我试着看看我是否在重复做任何可能不必要的事情,我纠正了一些。但是程序仍然很慢。
此外,我已将堆大小增加到 1500m,这是我可以达到的最大值。
有什么我可能做错了吗?
谢谢您的帮助!
编辑:分析结果首先我真的要感谢你们的评论。我已经更改了程序中的一些内容。我现在已经预编译了正则表达式,而不是直接String.split()
和其他优化。但是,在分析之后,我的addValues
方法花费的时间最长。所以,这是我的代码addValues
。有什么我应该在这里优化的吗?哦,我也startProcess
稍微改变了我的方法。
private HashMap<String, Integer> addValues(
HashMap<String, Integer> wordsCount, HashMap<String, Integer> temp) {
HashMap<String, Integer> merged = new HashMap<String, Integer>();
for (String x : wordsCount.keySet()) {
Integer y = temp.get(x);
if (y == null) {
merged.put(x, wordsCount.get(x));
} else {
merged.put(x, wordsCount.get(x) + y);
}
}
for (String x : temp.keySet()) {
if (merged.get(x) == null) {
merged.put(x, temp.get(x));
}
}
return merged;
}
EDIT2:即使经过如此努力,程序也没有按预期运行。我做了所有“慢方法”的优化,addValues
但没有奏效。所以我去了不同的路径,首先创建字典并为每个单词分配索引,然后再进行处理。让我们看看它的去向。谢谢您的帮助!