228063 logins uniques et 458448 logins rejetés car déjà existants.
228063 logins uniques et 458448 logins rejetés car déjà existants.
Optimisation du temps précédent, vu que la plupart du temps passé dans le traitement étais dans fLitLigne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 nomCheminFichier est une chaîne = "G:\temp\mdl_combo1\mdl_combo1.txt" IdFichier est un entier LigneLue est une chaîne nbrLigne est un entier = 1 duree est un réel tabRes est un tableau associatif de chaînes cle est une chaîne ChronoDébut(1) contenuFichier est une chaîne = fChargeTexte(nomCheminFichier) POUR TOUT CHAINE LigneLue DE contenuFichier SEPAREE PAR RC nbrLigne++ cle = ExtraitChaîne(LigneLue, 1, ":") SI tabRes[cle]..Occurrence = 0 ALORS tabRes[cle] = cle FIN FIN Trace (ChaîneConstruit("%1 ligne(s) / %2 lignes(s) sont uniques", tabRes..Occurrence, nbrLigne)) duree = ChronoFin(1) duree = duree / 1000 Trace(ChaîneConstruit("Le traitement a duré %1 seconde(s)", duree))Par contre ça ne fonctionnera que sur des fichiers de longueur < 2go et toujours à condition que l'on ai suffisamment de mémoire pour charger le fichier lu et créer le tableau de comparaison.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 228064 ligne(s) / 686513 lignes(s) sont uniques Le traitement a duré 1.792 seconde(s)
Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !
On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.
DelphiManiac
Vous pouvez encore enlever quelques lignes inutiles car le tableau associatif est sans doublon donc inutile de vérifier si ..occurrence = 0.
Par contre Zouzoukha veut enregistrer les résultats dans un fichier Hyperfile et c'est cette partie qui prend le plus de temps.
Ceci dit je vois à quel point mon pc commence à se faire vieux car pour le même traitement, il prend presque 3 fois plus de temps que le votre alors que mon code est encore plus light (pas de ExtraitChaine et pas de ..occurrence = 0) .
J'ai peut être loupé une étape de cette discussion mais j'ai une question :
As tu besoin de stocker le résultat de ton fichier sans doublons dans une BDD ?
Ou tu veux un programme qui t'affiche à l'écran ton fichier sans doublons (sans stockage dans une BDD) ?
------------------------------------------------------------------------------------------------------------------------------------------
Mon message vous a aidé, pensez à remercier . La discussion est résolue, n'oubliez pas le tag
------------------------------------------------------------------------------------------------------------------------------------------
Site perso : Formation, Expérience, Réalisations, ...
Blog : Le Blog de DSR57 - Programmation WinDev
Je ne vois pas où, dans le post initial, il est spécifier que l'on doit stocker le résultat en BDD. Il est juste indiquer qu'a l'heure actuelle, c'est la méthode qu'il avait choisi pour identifier les doublons.
Mais la remarque est pertinente
Pour en revenir à l'optimisation, il faudrait voir sur un gros volume de données, il doit y avoir moyen de même passer en multithread si cela devenait trop long.
Concernant le fait de ne pas avoir à tester ..occurence, vu que le tableau est déclaré sans doublons, c'est pas vraiment faux, mais pas vraiment juste :p Si l'on ne teste pas ..Occurence, je suppose (pas fait de vérification) que Windev va me sortir une erreur, donc il faudra tester l'erreur et je ne suis pas sur que le traitement de l'erreur soit moins long, mais ça serais à vérifier.
[Edit]Ah ben non, pas d'erreur si la clé existe déjà, il ignore juste l'ajout, donc on gagne quelques millièmes de secondes.
Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !
On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.
Question : plutôt qu'un flitligne(), si tu fais un fchargetexte et que tu traites la chaine lue (extractions), cela ne serai pas plus rapide ?
Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.
Sur internet, tout est vrai ! Honoré de Balzac
Make it real not fantasy... Herman Rarebell
Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !
On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.
Bonjour
A partir d'une procédure d'un Windevien, en l'adaptant à ton cas je divise par 4.5 le temps de traitement (3.1 s sur mon PC).
Je l'utilise souvent pour compter le nombre de lignes d'un fichier texte et actualiser la jauge.
Si je fais seulement le comptage, la durée du traitement sur ton fichier tombe a 1.4 s.
A essayer sur un fichier réel.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 PROCEDURE CompterLignes(FichierTexte) LOCAL NumFichierExterne est un entier ChaineLue est une chaîne TailleaLire est un entier = 1000 ListeRubriques est une chaîne IndiceDebutListeRub est un entier IndiceFinListeRub est un entier ChaineTraitee est une chaîne Compteur est un entier tabRes est un tableau associatif de chaînes cle est une chaîne NumFichierExterne = fOuvre(FichierTexte,foLecture) SI NumFichierExterne<>-1 ALORS ChronoDébut(1) ChaineTraitee="" BOUCLE ChaineLue=fLit(NumFichierExterne,TailleaLire) SI Taille(ChaineLue)=0 ALORS SORTIR SINON ChaineTraitee=ChaineTraitee+ChaineLue IndiceDebutListeRub=1 BOUCLE IndiceFinListeRub=Position(ChaineTraitee,RC,IndiceDebutListeRub) SI IndiceFinListeRub>0 ALORS ListeRubriques=ChaineTraitee[[IndiceDebutListeRub A (IndiceFinListeRub-1)]] SI ListeRubriques=EOT ALORS SORTIR Compteur++ // Ici ton code de recherche de doublon // ***************************** cle = ExtraitChaîne(ListeRubriques, 1, ":") SI tabRes[cle]..Occurrence = 0 ALORS tabRes[cle] = cle FIN // ***************************** SINON ChaineTraitee=ChaineTraitee[[IndiceDebutListeRub A]] SORTIR FIN IndiceDebutListeRub=IndiceFinListeRub+1 FIN FIN FIN fFerme(NumFichierExterne) Trace (ChaîneConstruit("%1 ligne(s) / %2 lignes(s) sont uniques", tabRes..Occurrence, Compteur)) duree est un réel duree = ChronoFin(1) duree = duree / 1000 Trace (ChaîneConstruit("Le traitement a duré %1 seconde(s)", duree)) Info(ChaîneConstruit("Le traitement a duré %1 seconde(s)", duree)) SINON Erreur("Imposible ouvrir le fichier : "+FichierTexte) FIN RENVOYER Compteur
Salut
Possible, voir même fort probable, que le bout de code ne soit pas 100% opérationnel et testé, c'étais plus pour démontrer le principe que pour valider complètement le traitement.
[edit]
Le fichier texte contient exactement 686512 ligne avec la dernière ligne à vide (je trouve donc une ligne de plus, vu que je ne teste pas les lignes vides, ni d'ailleurs les clés vide, ni encore moins que la valeur lu soit du style <quelque chose>:<quelque chose>) et mon code initialisait la variable de décompte de ligne à 1 (séquelle du code précédent) alors qu'il faut qu'elle soit initialisé à 0.
Ci dessous le code corrigé avec le test sur les lignes vides
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 nomCheminFichier est une chaîne = "G:\temp\mdl_combo1\mdl_combo1.txt" LigneLue est une chaîne nbrLigne est un entier = 0 duree est un réel cle est une chaîne //<Nom du tableau> est un tableau associatif [(<Options> [, <Valeur par défaut> [, <Type de clé> [,<Taille initiale>]]])] de <Type> tabRes est un tableau associatif (*, *, *, 1000000) de chaînes ChronoDébut(1) contenuFichier est une chaîne = fChargeTexte(nomCheminFichier) POUR TOUT CHAINE LigneLue DE contenuFichier SEPAREE PAR RC SI LigneLue <> "" ALORS nbrLigne++ cle = ExtraitChaîne(LigneLue, 1, ":") tabRes[cle] = cle FIN FIN Trace (ChaîneConstruit("%1 ligne(s) / %2 lignes(s) sont uniques", tabRes..Occurrence, nbrLigne)) duree = ChronoFin(1) duree = duree / 1000 Trace(ChaîneConstruit("Le traitement a duré %1 seconde(s)", duree))
Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !
On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.
Merci encore pour ton aide.
Maintenant le comptage simple de lignes tombe à 0.23 s
Bonjour,
Petite dérive au sujet du comptage de ligne, utilisez plutôt :
Nombre retourné en 168ms avec une seule ligne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part ChaîneOccurrence(<Fichier>,RC)
Oops désolé pour le retard!
Dis donc ca a évolué
En effet, je n'ai pas besoin de stocker dans un fichier HF!
Seulement je me servais du fichier H pour supprimer les doublons...
Merci pour toutes ces remontées!
J'ai de quoi grater
Edit : Par contre vous trouvez 686512 uniques?
alors qu'il devrait y avoir environ 680000 uniques et près de 6000 doublons
Je (nous à priori) trouve 228064 uniques, sachant que le test a été effectué sur la partie avant les ':'. Il n'étais pas précisé, il me semble, quelle étais la partie devant être testé, donc j'ai choisi arbitrairement ^^
Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !
On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.
Bien joué Delphi! maniac dans tes choix aussi?
Je peux avoir delphi:maniac et delphi:depressif
pas de doublon ds ce cas!
Ce choix peut-il faire écrouler les perfs?
Pas de raison, à première vue, que le fait de prendre la ligne entière comme clé soit pénalisant en terme de performance, sauf si la clé devenait excessivement longue. Et même dans ce cas, je ne suis pas sûr que la perte de performance soit vraiment importante.
Je soupçonne que Windev utilise un hash pour vérifier que la clé existe et que dans le cas ou le hash est trouvé, il compare les valeurs mémorisées pour ce hash avec la vrai clé. Donc la seule différence significative serait le calcul du hash.
Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !
On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.
Si le but c'est de dédoublonner un fichier de plus 1 Go, et si le taux de lignes uniques est élevé, alors un tableau associatif n'est pas une bonne solution, à cause de l'usage mémoire. (déjà, rien que le fChargeTexte, je m'en serais passé)
Il existe une fonction HImporteTexte, mais elle est infiniment plus lente que dans SQL Server ou MySQL.
Dans les circonstances actuelles et en fonction de ce que je sais, la demande étant lié au temps de traitement, la seule solution que je vois c'est de passer par la mémoire et non par une table.
Concernant la comparaison de HImporteTexte avec les fonctions équivalentes de mysql et sqlserver, la différence de vitesse est à mon avis, du fait que les 2 sgbd cités stockent les données en mémoire le temps du traitement (mise en cache), l'écriture se faisant en différé, donc le problème de mémoire resterait.
Même si Hyperfile n'est pas au top niveau base de données, je ne pense pas que que l'on ai des différences de temps de traitement énormes, hormis bien sûr comme dis précédemment que les 2 moteurs de base de données utilisent intensivement la mémoire pour optimiser les traitements, ce qui ne semble pas être le cas de HyperFile.
Le choix de fChargeTexte reste un choix d'optimisation du temps de traitement, l'option boucle sur fLitLigne est mal géré par windev, windev ne gérant pas de buffer de lecture à priori, ou alors je n'ai pas trouvé.
L'option intermédiaire serait gérer manuellement les buffers, ie, de lire des blocs de données de taille raisonnable (10 mo par exemple) et de gérer manuellement le découpage des lignes et la lecture des blocs de données pour éviter le temps perdu par Windev à lire lire par ligne.
L'autre option, mais je ne me risquerait pas à le faire sous Windev, quoi que ça doit être faisable, serais de passer pas les fichiers mappés en mémoire.
Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !
On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.
Non, un SGBD est fait pour travailler sans charger tout en mémoire, c'est le B.A.-BA. On peut le limiter à une occupation maxi.
La différence de perf peut être due à des tas de paramètres, et elle est vraiment notable. Quand j'aurai le temps, je ferai un test BULK INSERT Vs. HImporteTexte.
Là, votre appli va allouer disons entre 3 et 10 fois la taille du fichier source. 3 c'est même pas possible, puisqu'on a le fChargeTexte, la clé du tableau associatif, et la valeur du tableau associatif. A moins que WinDev fasse du copy-on-write sur les chaînes, ce dont je doute évidemment.
Déjà, dans le tableau associatif vous n'avez pas besoin de mettre la ligne dans la valeur, mais uniquement dans la clé (la valeur peut être un entier sur 1 par exemple).
La demande, c'est des fichiers de plus de 1 Go d'après le titre du sujet. Donc plus de 3 Go ça commence à faire, vous ne trouvez pas ?
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager