Я написал следующую функцию для расчета размеров URL.
Входные данные представляют собой предварительно построенную карту, отображающую filetype-> object, которая содержит набор строк url.
Я запускаю его на наборе из 3000 URL, и когда я увеличиваю количество потоков до 20, я получаю лучшие результаты при каждом запуске. после 20 потоков производительность начинает снижаться.
Моя первоначальная цель состояла в том, чтобы запустить его на 500 000 URL Поэтому я подумал, что я запусту его, используя 200 потоков в ThreadPool.
результат, который я получил, был:
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 6. Size: 14 MB. Time took to calculate: 1010
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 2863. Size: 3 GB. Time took to calculate: 61004
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 3481. Size: 3 GB. Time took to calculate: 121002
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 3691. Size: 3 GB. Time took to calculate: 181004
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 3706. Size: 3 GB. Time took to calculate: 241004
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 3838. Size: 4 GB. Time took to calculate: 301004
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 4596. Size: 4 GB. Time took to calculate: 361004
FileType: pdf. CountTotalFiles: 394231 .CountCalcedSize: 5059. Size: 5 GB. Time took to calculate: 421008
и это было довольно обидно, потому что очень скоро, сразу после ~ 3000 URL, производительность снижается, и за минуту обрабатывается только 100-150 URL. Как видно, 2000 URL были обработаны в первую минуту.
Я делаю что-то не так, используя пул потоков, как я?
Или здесь есть еще одно узкое место?
void getSize(Map<String, Files> map) throws IOException {
final BufferedWriter bw = new BufferedWriter(new FileWriter("bad_files.txt"));
Set<Entry<String, Files>> entrySet = map.entrySet();
for (Entry<String, Files> entry : entrySet) {
final List<Long> sizeList = new ArrayList<Long>();
Files filesObject = entry.getValue();
HashSet<String> urlsSet = filesObject.urlsSet;
ExecutorService pool = Executors.newFixedThreadPool(200);
final long startTime = System.currentTimeMillis();
final String k = entry.getKey();
final Files value = entry.getValue();
Timer t= new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
long size = 0;
for (Long s : sizeList) {
size+=s;
}
System.out.println("FileType: " + k + ". CountTotalFiles: " + value.urlsSet.size() + " .CountCalcedSize: " + sizeList.size() +". Size: " + FileUtils.byteCountToDisplaySize(size) + ". Time took to calculate: " + (System.currentTimeMillis() - startTime));
}
}, 1000, 60000);
for (final String urlStr : urlsSet) {
Runnable call = new Runnable() {
@Override
public void run() {
HttpURLConnection urlCon = null;
try {
URL url= new URL(urlStr);
urlCon = (HttpURLConnection) url.openConnection();
// if (url.getProtocol().equals("https")) {
// setSSLContext((HttpsURLConnection)urlCon);
// }
if ( urlCon.getResponseCode() != HttpURLConnection.HTTP_OK) {
bw.append("Response: " + urlCon.getResponseCode() + " " +urlStr + "\n");
} else {
sizeList.add(Long.valueOf(urlCon.getContentLength()));
}
// urlCon.disconnect();
} catch (Exception e) {
try {
bw.append(e.getMessage() + " " +urlStr + "\n");
// urlCon.disconnect();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
};
pool.submit(call);
};
pool.shutdown();
try {
pool.awaitTermination(100, TimeUnit.DAYS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long size = 0;
for (Long s : sizeList) {
size+=s;
}
System.out.println("FileType: " + entry.getKey() + ". CountTotalFiles: " + entry.getValue().urlsSet.size() + " .CountCalcedSize: " + sizeList.size() +". Size: " + FileUtils.byteCountToDisplaySize(size) + ". Time took to calculate: " + (System.currentTimeMillis() - startTime));
}
bw.flush();
bw.close();
}