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"); } } }