我的输入数据是一个列表中的 50,000 条(或更多)电子邮件消息,并且在 to、cc 和 bcc 中的多个收件人之间存在大量重复。因此,我需要从此列表中提取唯一消息。
我必须比较 Message 的某些属性(发件人、收件人列表和包含(仅限字符串))以确定是否相同。
现在,我将这 50,000 条消息分成 50 个小 1000 条消息列表,并在其线程中运行每个小列表的重复项。
所有线程都将其输出添加到一个列表中,最后我检查该线程中的重复项。当我这样做时,我的 JVM 达到了 1.25 GB 内存。
因此,如果我尝试推送超过 50,000 条消息,则会出现内存不足错误。
我有一个名为 的方法removeDeduplicate(array of messages, blank list)
,它将消息数组和空列表作为输入,并在该空白列表中返回唯一消息。这是我的代码:
public Message[] processForDeduplication(Message[] msgs) throws MessagingException, IOException, InterruptedException {
final List<Message> output = new ArrayList<Message>();
if(msgs.length < MAX_MSG){
output.addAll(removeDeduplication(msgs, new ArrayList<Message>()));
} else {
List<Thread> threads = new ArrayList<Thread>();
int index = 0, lastIndex = MAX_MSG;
while(index < msgs.length){
if(lastIndex >= msgs.length) {
lastIndex = msgs.length;
}
final Message[] temp = Arrays.copyOfRange(msgs, index, lastIndex);
Thread t = new Thread(new Runnable(){
@Override
public void run() {
try {
output.addAll(removeDeduplication(temp, new ArrayList<Message>()));
} catch (MessagingException ex) {
logger.error(EmailComparator.class.getName() + ex);
} catch (IOException ex) {
logger.error(EmailComparator.class.getName() + ex);
}
}
});
t.start();
threads.add(t);
index = lastIndex;
lastIndex = lastIndex + MAX_MSG;
}
for(Thread t: threads){
while(t.isAlive()){
Thread.sleep(100);
}
}
threads = null;
}
List<Message> results = removeDeduplication(convertToArray(output), new ArrayList<Message>());
return convertToArray(results);
}
我也在尝试微调我的代码以提高内存和性能。现在完成 50,000 条记录大约需要 12-15 秒,我希望是 5-6 秒。