9
votes

BIBLIOTHÈQUES DE TRANSFERTS (TRANSFERTS ENDITIONS FINITIES), C ++ ou Java

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.

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.

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.

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?

Merci tout.


0 commentaires

6 Réponses :


4
votes

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.

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.

bonne chance!


0 commentaires

2
votes

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é.


0 commentaires

0
votes

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.

Je pense que cela devrait être la principale raison de choisir C ++ sur Java.


0 commentaires

2
votes

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.


0 commentaires

0
votes

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.

Une série de pots de blog la décrire .
Le code est situé
sur svn .

mise à jour: Je l'ai porté à Java ici


0 commentaires

0
votes

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


0 commentaires