J'ai un problème à résoudre en utilisant FSTS. Fondamentalement, je vais faire un analyseur morphologique et, en ce moment, je dois travailler avec de grands transducteurs. La performance est le gros problème ici. P>
Récemment, j'ai travaillé à C ++ dans d'autres projets où la performance compte, mais maintenant, je considère Java, car les avantages de Java et parce que Java s'améliore. P>
J'ai étudié des comparaisons entre Java et C ++, mais je ne peux pas décider de quelle langue je devrais utiliser pour ce problème spécifique car elle dépend de la libérations de la lib. P>
Je ne trouve pas beaucoup d'informations sur les Libs de Java, alors ma question est la suivante: y a-t-il des libs de Java open source dans lesquelles la performance est bonne, comme La Toolkit de RWTH FSA que j'ai lu dans un article qui est le plus rapide C ++ Lib? P>
Merci tout. p>
6 Réponses :
Quels sont les "avantages" de Java, à vos fins? Quel problème spécifique cette plate-forme résoudra-t-elle que vous avez besoin? Quelle est la contrainte de performance que vous devez envisager? Les "comparaisons" étaient-ils justes, car Java est en fait extrêmement difficile à repasser. Donc, C ++, mais vous pouvez au moins obtenir des garanties de limites algorithmiques de STL. P>
Je vous suggère de regarder Openfst et les outils de transducteur AT & T Finit-State. Il y en a d'autres, mais je pense que votre souci de Java met le chariot devant le cheval - concentrez-vous sur ce qui résout votre problème bien. p>
bonne chance! p>
http://jautomata.sourceforge.net/ et http://www.cs.duke.edu/csed/jfflap/ est basé sur les bibliothèques de machines à états finies Java, bien que je n'ai pas t avoir de l'expérience en utilisant eux donc je ne peux pas commenter l'efficacité. P>
Le problème ici est la taille minimale de vos objets en Java. En C ++, sans méthodes virtuelles et identification de type temporel d'exécution, vos objets pèsent exactement leur contenu. Et le temps que votre automate prend pour manipuler la mémoire a un impact important sur la performance. P>
Je pense que cela devrait être la principale raison de choisir C ++ sur Java. P>
Je suis l'un des développeurs du Morfologik-stemming bibliothèque. C'est pur Java et sa performance est très bonne, à la fois lorsque vous construisez l'automate et lorsque vous l'utilisez. Nous l'utilisons pour une analyse morphologique en languagetool. P>
OpenFST est un cadre de transducteur d'état fini c ++ qui est vraiment complet. Certaines personnes de CMU l'ont portée à Java pour une utilisation dans leur traitement de langue naturelle. p>
Une série de pots de blog la décrire a >.
Le code est situé sur svn . P >
mise à jour: Je l'ai porté à Java ici P>
Lucene a un excellent Mise en œuvre de la FST, facile à utiliser et haute performance, faisant des moteurs de requête comme Elasticsearch, Solr fournit une requête basée sur des sous-secondes très rapide.let moi prenons un exemple:
import com.google.common.base.Preconditions;
import org.apache.lucene.store.ByteArrayDataInput;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.GrowableByteArrayDataOutput;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IntsRefBuilder;
import org.apache.lucene.util.fst.Builder;
import org.apache.lucene.util.fst.FST;
import org.apache.lucene.util.fst.PositiveIntOutputs;
import org.apache.lucene.util.fst.Util;
import java.io.IOException;
public class T {
private final String inputValues[] = {"cat", "dog", "dogs"};
private final long outputValues[] = {5, 7, 12};
// https://lucene.apache.org/core/8_4_0/core/org/apache/lucene/util/fst/package-summary.html
public static void main(String[] args) throws IOException {
T t = new T();
FST<Long> fst = t.buildFSTInMemory();
System.out.println(String.format("memory used for fst is %d bytes", fst.ramBytesUsed()));
t.searchFST(fst);
byte[] bytes = t.serialize(fst);
System.out.println(String.format("length of serialized fst is %d bytes", bytes.length));
fst = t.deserialize(bytes);
t.searchFST(fst);
}
private FST<Long> buildFSTInMemory() throws IOException {
// Input values (keys). These must be provided to Builder in Unicode sorted order! Use Collections.sort() to sort inputValues first.
PositiveIntOutputs outputs = PositiveIntOutputs.getSingleton();
Builder<Long> builder = new Builder<Long>(FST.INPUT_TYPE.BYTE1, outputs);
BytesRef scratchBytes = new BytesRef();
IntsRefBuilder scratchInts = new IntsRefBuilder();
for (int i = 0; i < inputValues.length; i++) {
// scratchBytes.copyChars(inputValues[i]);
scratchBytes.bytes = inputValues[i].getBytes();
scratchBytes.offset = 0;
scratchBytes.length = inputValues[i].length();
builder.add(Util.toIntsRef(scratchBytes, scratchInts), outputValues[i]);
}
FST<Long> fst = builder.finish();
return fst;
}
private FST<Long> deserialize(byte[] bytes) throws IOException {
DataInput in = new ByteArrayDataInput(bytes);
PositiveIntOutputs outputs = PositiveIntOutputs.getSingleton();
FST<Long> fst = new FST<Long>(in, outputs);
return fst;
}
private byte[] serialize(FST<Long> fst) throws IOException {
final int capicity = 32;
GrowableByteArrayDataOutput out = new GrowableByteArrayDataOutput(capicity);
fst.save(out);
return out.getBytes();
}
private void searchFST(FST<Long> fst) throws IOException {
for (int i = 0; i < inputValues.length; i++) {
Long value = Util.get(fst, new BytesRef(inputValues[i]));
Preconditions.checkState(value == outputValues[i], "fatal error");
}
}
}