0
votes

Besoin d'optimiser mon code de clojure qui prend trop de temps

J'ai un fichier journal, qui est de 1,6 Go de taille et contient 2 millions d'enregistrements. Je lis le contenu de la connexion dans une chaîne, effectuant une certaine transformation et écrivez le contenu sur un autre canal.

Enfin, j'écris le contenu de la deuxième chaîne dans un fichier.

Mon code fonctionne bien et les résultats sont comme prévu. Cependant, toute l'opération prend environ 45 secondes, ce qui est trop long.

J'ai besoin de réduire le temps pris. xxx

Je m'excuse pour la mauvaise indentation et la mise en forme.


1 commentaires

Avez-vous envisagé d'utiliser un profileur? J'utilise Yourkit mais Visualvm est gratuit.


3 Réponses :


1
votes

transformer fait plusieurs opérations extrêmement coûteuses à chaque fois par la boucle. Nombre et NTH sur une séquence paresseuse prennent chacun O (n) heure. Au lieu d'utiliser l'une de ces deux, traitez la séquence paresseusement avec premier et suivant .


3 commentaires

Je soupçonne que je compte sur un SEQ paresseux n'est que O (n) la première fois. Bien entendu, cela obligera tout le SEQ à se rendre compte et non paresseux.


Non, c'est lent à chaque fois.


J'apprends quelque chose de nouveau tous les jours. Merci - alla et regardé Lazyseq.java. Ne s'attendait pas à ça.



1
votes

Je n'aime pas le code-golf, mais cela semble que cela réduirait assez simplement. Nous voulons compter la fréquence de référence, alors faites simplement cela:

  (with-open [reader (clojure.java.io/reader "My_Big_Log")]
    (frequencies
     (map #(re-find #"[a-z]+\.[a-z]+\.[a-z]+")
          (line-seq reader))))


1 commentaires

Votre réduction a besoin d'un {} argument. Mieux, cependant, serait de ne pas réimprimer fréquences : (fréquences (mappe # (retrouver ...) (lecteur de ligne-SEQ)))



0
votes

Trier code> sur 2M Les entrées sont lentes. Plus Nombre code> et NTH code> sont également coûteux sur la séquence paresseuse. Vous pouvez les éviter (ainsi que toutes les séquences intermédiaires) avec un transducteur. Sur mon MBP, 2M enregistrements ont pris environ 5 secondes.

Referrer 0: h.i.j
Number of entries associated with this referrer: 399065
Referrer 1: k.l.m
Number of entries associated with this referrer: 400809
Referrer 2: a.b.c
Number of entries associated with this referrer: 400186
Referrer 3: c.d.e
Number of entries associated with this referrer: 399667
Referrer 4: m.n.o
Number of entries associated with this referrer: 400273


3 commentaires

Bonjour, merci de m'aider, votre approche est définitivement plus élégante, mais sur ma machine qui est un ThinkPad avec des concerts de mémoire I5 ​​et 16, il prend environ 40 secondes pour produire le résultat.


@ Les courses sucessives ont pris une fois de temps différent, la première a pris 41 secondes et une seconde a pris 46 secondes. imgur.com/61ef1ak . Ceci est le lien vers la capture d'écran.


Veuillez vérifier votre performance d'E / S sur disque. Une autre chose à essayer est de mettre à niveau JDK à 11.0.1 (pas 11.0.2) et assurez-vous que Core.Async est le dernier. Sur une boîte Windows avec JDK 8 et CLOJURE 1.10, ma version par rapport à votre version est 2S: 32S.