Я аннотирую огромное количество строк как CoreDocuments через Stanford Corenlp. Конвейеры StanfordCoreNLP имеют внутреннюю функцию для многопоточного аннотирования для оптимизации процесса, однако, насколько я вижу, объекты CoreDocument не могут использовать эту функцию в версии, которую я запускаю, - это stanford-corenlp-full-2018-10-05.
Поскольку я не мог создавать конвейерные аннотации коллекций CoreDocuments, я вместо этого попытался оптимизировать отдельные аннотации, помещая их в многопоточные методы. У меня нет проблем с многопоточным окружением. Я получаю все результаты обратно, как и ожидалось, мой единственный недостаток - это потребление времени. Я попробовал около 7 различных реализаций, и это были 3 самых быстрых:
//ForkJoinPool is initialized in the main method in my application
private static ForkJoinPool executor = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false);
public static ConcurrentMap<String, CoreDocument> getMultipleCoreDocumentsWay1(Collection<String> str) {
ConcurrentMap<String, CoreDocument> pipelineCoreDocumentAnnotations = new MapMaker().concurrencyLevel(2).makeMap();
str.parallelStream().forEach((str1) -> {
CoreDocument coreDocument = new CoreDocument(str1);
pipeline.annotate(coreDocument);
pipelineCoreDocumentAnnotations.put(str1, coreDocument);
System.out.println("pipelineCoreDocumentAnnotations size1: " + pipelineCoreDocumentAnnotations.size() + "\nstr size: " + str.size() + "\n");
});
return pipelineCoreDocumentAnnotations;
}
public static ConcurrentMap<String, CoreDocument> getMultipleCoreDocumentsWay4(Collection<String> str) {
ConcurrentMap<String, CoreDocument> pipelineCoreDocumentAnnotations = new MapMaker().concurrencyLevel(2).makeMap();
str.parallelStream().forEach((str1) -> {
try {
ForkJoinTask<CoreDocument> forkCD = new RecursiveTask() {
@Override
protected CoreDocument compute() {
CoreDocument coreDocument = new CoreDocument(str1);
pipeline.annotate(coreDocument);
return coreDocument;
}
};
forkCD.invoke();
pipelineCoreDocumentAnnotations.put(str1, forkCD.get());
System.out.println("pipelineCoreDocumentAnnotations2 size: " + pipelineCoreDocumentAnnotations.size() + "\nstr size: " + str.size() + "\n");
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(Parsertest.class.getName()).log(Level.SEVERE, null, ex);
}
});
return pipelineCoreDocumentAnnotations;
}
public static ConcurrentMap<String, CoreDocument> getMultipleCoreDocumentsWay7(ConcurrentMap<Integer, String> hlstatsSTR) {
RecursiveDocumentAnnotation recursiveAnnotation = new RecursiveDocumentAnnotation(hlstatsSTR, pipeline);
ConcurrentMap<String, CoreDocument> returnMap = new MapMaker().concurrencyLevel(2).makeMap();
executor.execute(recursiveAnnotation);
try {
returnMap = recursiveAnnotation.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(Parsertest.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("reached end\n");
return returnMap;
}
RecursiveDocumentAnnotation class:
public class RecursiveDocumentAnnotation extends RecursiveTask<ConcurrentMap<String, CoreDocument>> {
private String str;
private StanfordCoreNLP nlp;
private static ConcurrentMap<String, CoreDocument> pipelineCoreDocumentAnnotations;
private static ConcurrentMap<Integer, String> hlstatsStrMap;
public static ConcurrentMap<String, CoreDocument> getPipelineCoreDocumentAnnotations() {
return pipelineCoreDocumentAnnotations;
}
public RecursiveDocumentAnnotation(ConcurrentMap<Integer, String> hlstatsStrMap, StanfordCoreNLP pipeline) {
this.pipelineCoreDocumentAnnotations = new MapMaker().concurrencyLevel(2).makeMap();
this.str = hlstatsStrMap.get(0);
this.nlp = pipeline;
this.hlstatsStrMap = hlstatsStrMap;
}
public RecursiveDocumentAnnotation(ConcurrentMap<Integer, String> hlstatsStrMap, StanfordCoreNLP pipeline,
ConcurrentMap<String, CoreDocument> returnMap) {
this.str = hlstatsStrMap.get(returnMap.size());
this.nlp = pipeline;
this.hlstatsStrMap = hlstatsStrMap;
this.pipelineCoreDocumentAnnotations = returnMap;
}
@Override
protected ConcurrentMap<String, CoreDocument> compute() {
CoreDocument coreDocument = new CoreDocument(str);
nlp.annotate(coreDocument);
pipelineCoreDocumentAnnotations.put(str, coreDocument);
System.out.println("hlstatsStrMap size: " + hlstatsStrMap.size() + "\npipelineCoreDocumentAnnotations size: " + pipelineCoreDocumentAnnotations.size()
+ "\n");
if (pipelineCoreDocumentAnnotations.size() >= hlstatsStrMap.size()) {
return pipelineCoreDocumentAnnotations;
}
RecursiveDocumentAnnotation recursiveAnnotation = new RecursiveDocumentAnnotation(hlstatsStrMap, nlp, pipelineCoreDocumentAnnotations);
recursiveAnnotation.fork();
return recursiveAnnotation.join();
} }
Параллельное время1: 336562 мс.
Параллельное время4: 391556 мс.
Параллельное время7: 491639 мс.
Честно говоря, было бы величайшим, если бы сам конвейер мог каким-либо образом выполнять мультианнотацию, однако, пока я не знаю, как этого добиться, я надеюсь, что кто-то может объяснить мне, как оптимизировать аннотации CoreDocument по отдельности.
PS: Объединение всех строк в единый документ с сердцевиной для аннотации также не будет тем, что я хочу, так как мне нужны индивидуальные документы с сердцевиной для последующих сравнений.