IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Rechercher / remplacer rapidement du texte


Sujet :

Shell et commandes GNU

  1. #21
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    ça dépend complètement du nombre de substitutions à effectuer, si on considère un fichier de 20G avec 1 seule substitution à effectuer, ma méthode revient exactement au même que la tienne, c'est à dire 1 open, 1 seek, 1 write, 1 close
    Dans le cas qui concerne ce thread il n'y a qu'une seule substitution à effectuer et on sait à peu près où elle se trouve. Moins d'une seconde comparé à cinq minutes, je ne dirais pas que ça revient "exactement au même" ;-)

    maintenant si on considère quelque chose de moins aberrant, et possiblement plus proche de la réalité, à savoir un fichier de 20G avec admettons 200 substitutions a effectuer ("<day>20160202</day>" fait 19 octets, dans 4096 octets on peut en placer à peine plus de 200, donc on est dans un cas encore extrême)
    • soit on découpe soigneusement un bloc de 4096 octets qui contient les 200 occurrences, c'est très rapide
    • soit on passe par un fichier temporaire comme avec sed -i, c'est très lent
    • soit on effectue 200 fois à la suite les appels open, seek, write, close, et c'est un peu plus lent que la première solution, mais ça reste tout de même extrêmement rapide par rapport à la deuxième, pour ainsi dire on ne doit pas excéder une ou deux paires de secondes dans le pire des cas, donc il faut tout de même relativiser
    Le troisième cas prends environ cinq minutes, pas deux secondes.
    un truc simple sinon, tu as déjà essayé de coder une fonction de journalisation dans un programme qui déroule très vite ? l'erreur classique est de mettre open et close dans la fonction, ce qui plombe systématiquement les perfs, la solution adaptée consiste à garder le fichier ouvert et à ne le fermer qu'à la fin du programme, c'est donc que les ouvertures/fermetures de fichier ne sont pas sans conséquence, loin de là
    Quand on travaille avec un fichier de 20 Go, le temps pris par de multiples ouvertures/fermetures de fichier peut souvent être considéré comme négligeable, mais je suis bien sûr d'accord avec le fait qu'il ne sert à rien de multiplier les ouverture/fermetures sans raison.

    tu parles du grep j'imagine, clairement ça n'est pas optimum, mais on s'en fout la lecture ne prend pas tant de temps que ça, c'est de réécrire tout le fichier dans le cadre d'un fichier temporaire qui est consommateur
    "Pas tant de temps que çà", c'est vite dit...

    Les temps de lecture et d'écriture d'un fichier sont du même ordre de grandeur, quelque chose comme 50 à 100 Mo/s (sauf si tu es sur ssd). Il te faut donc environ 5 minutes pour lire un fichier de 20 Go, puis 5 minutes pour le réécrire. Ce sont bien les 10 minutes dont parle Bouga74. On ne se fout donc pas du tout de la lecture. D'autre part, passer par un fichier temporaire ou pas, ça n'a pas grande importance, c'est même probablement plus rapide que modifier la totalité du fichier original in-situ.

    euh... non.
    Si. Si les chaines à remplacer se trouvent dans les même blocs disque, tu vas réécrire plusieurs fois ces mêmes blocs, et l'OS va même les re-relire à chaque écriture. Cette deuxième lecture sera cependant en cache.

    je crois que tu te mélanges entre les blocs virtuels qu'on paramètre à dd et les secteurs physiques du disque, dont on a absolument pas connaissance
    les blocs définis par bs= et count= sont ni plus ni moins que l'équivalent des paramètres size et nmemb de la fonction fread(3)
    Je ne me mélange pas et c'est bien l'accès aux secteurs physiques du disque qui peut poser problème ici. L'OS va sûrement essayer d'optimiser les écritures multiples vers le même bloc le cas échéant, mais c'est quand même très lourd.
    ɹǝsn *sıɹɐlos*

  2. #22
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    le plus simple c'est encore de faire le test

    on crée le fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # time base64 /dev/urandom | head -c 1073741824 > bigfile    # 1G
    real    0m48.348s
    # cp bigfile bigfile2
    # time for i in {1..10}; do cat bigfile2 >> bigfile; done
    real    3m53.222s
    # rm bigfile2
    # du -h bigfile
    12G     bigfile
    # for i in {1..200}; do echo -ne "bouzin " >> header; done
    # cat header | dd of=bigfile bs=1 conv=notrunc
    1400+0*enregistrements lus
    1400+0*enregistrements écrits
    1400*octets (1,4 kB) copiés, 0,00563064*s, 249 kB/s
    on a donc un fichier d'environ 12G avec en tête 200 occurrences du mot "bouzin" qu'on voudra remplacer par "BOUZIN", le fichier a mis ~4min à se créer, mais on pourrait arguer que c'est la faute de base64 ou de /dev/urandom (qui sait...)

    on fait donc un test comme le ferait sed -i en gros, avec lecture + écriture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # time cp bigfile bigfile2
    ^C
    real    11m16.115s
    j'ai interrompu, c'était long (+11min), le fichier avait copié 9G en gros

    et un test de lecture (+ recherche) comme le ferait grep :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # time grep -boF coincoin bigfile 
    real    1m53.033s
    on est donc pas tout à fait dans les mêmes ordres de grandeur

    du coup on test ma méthode, censée prendre 5min, réécrire pleins de blocs etc.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # time grep -boF "bouzin" bigfile | cut -d':' -f1 | while read offset; do echo -ne "BOUZIN" | dd of=bigfile conv=notrunc bs=1 seek=${offset} 2>/dev/null; done
    real    1m15.885s
    va savoir comment, on a gagné près de 40s

    et on fait la manip inverse, en coupant simplement la chique au grep au bout d'"une paire ou deux de secondes"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # time grep -boF "BOUZIN" bigfile | cut -d':' -f1 | while read offset; do echo -ne "bouzin" | dd of=bigfile conv=notrunc bs=1 seek=${offset} 2>/dev/null; done
    ^C
    real    0m4.968s
    # head -1 bigfile | sed -e 's/ /\n/g' | sort | uniq -c
        200 BOUZIN
          1 kIPrM2PXyAFpIc4g6MYkRm4zQqMjtCCWvykaMhAEJS90U3qblYZESaiyHxXt91
    interrompu manuellement donc, et on a bien effectué nos 200 substitutions en une poignée de secondes comme je te le disais

    Citation Envoyé par jlliagre Voir le message
    Dans le cas qui concerne ce thread il n'y a qu'une seule substitution à effectuer et on sait à peu près où elle se trouve.
    effectivement j'avais pas fait gaffe qu'il n'y a en fait qu'une seule substitution à effectuer à priori (c'est encore pire )

    Moins d'une seconde comparé à cinq minutes, je ne dirais pas que ça revient "exactement au même" ;-)
    (...)
    Le troisième cas prends environ cinq minutes, pas deux secondes.
    donc non, et on ne parle pas du grep mais bien du "troisième cas" à savoir effectuer 200 substitutions en réouvrant à chaque fois le fichier, en une paire de secondes c'est torché

    "Pas tant de temps que çà", c'est vite dit...
    en effet, ça prend son temps (+1min pour un fichier de 12G, on peut envisager 2 ou 3min pour un fichier de 20G en toute logique), mais on est loin du temps mis pour créer un fichier temporaire à l'identique comme le fait sed -i (+10min pour un fichier de 12G)

    Les temps de lecture et d'écriture d'un fichier sont du même ordre de grandeur
    on revient pas là dessus, cf au dessus donc, accessoirement si on a coutume de mesurer les débits en lecture ET en écriture d'un disque c'est surement qu'ils ne sont pas identiques

    Il te faut donc environ 5 minutes pour lire un fichier de 20 Go, puis 5 minutes pour le réécrire. Ce sont bien les 10 minutes dont parle Bouga74. On ne se fout donc pas du tout de la lecture.
    ben même si on laisse aller le grep à son terme on va un peu plus de 5x plus vite que le traitement initial, mais bon ok, on s'en fout pas de la lecture effectivement

    D'autre part, passer par un fichier temporaire ou pas, ça n'a pas grande importance, c'est même probablement plus rapide que modifier la totalité du fichier original in-situ.
    j'imagine que tu parles du fichier temporaire dans le cadre de ta méthode (c'est à dire un bout de fichier uniquement), je parlais du fichier temporaire comme le fait un sed, c'est à dire en recopiant l'intégralité du fichier (c'est exactement ce que tu dis quelques lignes plus haut sur les 10mins dont parle Bouga74)

    Si. Si les chaines à remplacer se trouvent dans les même blocs disque, tu vas réécrire plusieurs fois ces mêmes blocs, et l'OS va même les re-relire à chaque écriture. Cette deuxième lecture sera cependant en cache.
    j'imagine que tu parles au niveau de ce que fait le driver (je vois que ça), mais ça n'est pas pertinent du tout, non seulement comme démontré l'impact sur la substitution de 200 occurrences est quasi nul à ce stade, mais en plus il n'y a qu'une seule occurrence à remplacer comme tu l'as fait remarquer

    c'est bien l'accès aux secteurs physiques du disque qui peut poser problème ici (...) c'est quand même très lourd.
    du coup non je me rends pas bien compte de la lourdeur du problème là, en effet.

  3. #23
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut
    @BufferBob: tu as tenu compte de la "chauffe" du système dans tes tests ?

    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
    $ du -h x.csv
    9,2G    x.csv
    $ time wc -l x.csv
    57367730 x.csv
     
    real    11m52.521s
    user    0m1.247s
    sys     0m6.521s
    $ time wc -l x.csv
    57367730 x.csv
     
    real    0m2.845s
    user    0m0.626s
    sys     0m2.214s
    $ time grep totototo x.csv
     
    real    0m5.662s
    user    0m4.083s
    sys     0m1.573s
    Cordialement.

  4. #24
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    @BufferBob: tu as tenu compte de la "chauffe" du système dans tes tests ?
    y'a une partie de mise en cache oui, les 40s de diff entre le premier grep (nu) et le deuxième (oneliner) viennent possiblement de là, mais même sans le cache du système on atteindra jamais le temps mis pour écrire le fichier, on est sur un ratio supérieur à x5 là

    en clair le grep met du temps à parcourir tout le fichier c'est vrai, mais avec un peu de mise en cache il est encore un peu accéléré, dans tous les cas de figure on est bien en dessous du temps mis par un sed -i, quant à dd, même chainé 200 fois il ne prend quasiment rien comme temps et les considérations atomiques au niveau disque ne sont pas pertinentes

  5. #25
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut
    Mouais, tu es gentil sur le tout petit peu de gain avec le cache, perso, j'ai un big ratio:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ du -hs xa*hash
    817M    xaahash
    817M    xabhash
    817M    xachash
    816M    xadhash
    817M    xaehash
    818M    xafhash
    817M    xaghash
    817M    xahhash
    817M    xaihash
    820M    xajhash
    825M    xakhash
    391M    xalhash
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ time grep totototo xa*hash
     
    real    13m40.146s
    user    0m6.182s
    sys     0m5.730s
    $ time grep totototo xa*hash
     
    real    0m6.470s
    user    0m4.141s
    sys     0m2.323s
    Et un exemple de cp avec le x.csv en cache.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ time cp x.csv XA
     
    real    0m7.750s
    user    0m0.028s
    sys     0m7.694s
    $ du -hs XA
    9,2G    XA
    Cordialement.

  6. #26
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    @BufferBob: On n'est pas dans les conditions du cas qui nous intéresse. La question initiale parle de nombreux fichiers volumineux à traiter à la suite, ils ne seront donc pas dans le cache alors que la plupart des tests présentés travaillent beaucoup en RAM.

    Les mesures d'écriture ne sont pas forcément pertinentes non plus, car les commandes rendent la main avant que les données soient effectivement sur disque. Sur une opération unitaire, pourquoi pas, mais si on enchaîne les traitements comme demandé ici, il risque d'y avoir une grosse contention disque.
    ɹǝsn *sıɹɐlos*

  7. #27
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    laccessoirement si on a coutume de mesurer les débits en lecture ET en écriture d'un disque c'est surement qu'ils ne sont pas identiques
    Je n'ai pas écrit qu'ils étaient identiques mais du même ordre de grandeur. La différence est en général de l'ordre de 10% pour des accès séquentiels à haut débit, la lecture étant plus rapide que l'écriture.
    Pour des accès aléatoires, c'est plus compliqué, surtout si on est multi-threadé.
    ɹǝsn *sıɹɐlos*

  8. #28
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Mouais, tu es gentil sur le tout petit peu de gain avec le cache, perso, j'ai un big ratio
    oui si tu veux, le cache c'est très utile c'est vrai, et comme ça ne fonctionne qu'en lecture ça tend à dire que ma solution (dans laquelle c'est surtout la lecture du grep qui prend du temps) est finalement plus performante que je ne le prétendais

    pour la petite info j'ai refais les mesures depuis ce matin, et effectivement la mesure sur le cp était faussée à l'arrivée (testé 3x chacun, en mettant le fichier en cache au préalable) je trouve toujours ~2min en lecture et 5min en écriture pour un fichier de 12G

    Citation Envoyé par jlliagre Voir le message
    La question initiale parle de nombreux fichiers volumineux à traiter
    au temps pour moi, c'est moi qui ai encore une fois mal lu décidément, mea maxima culpa

    (...) ils ne seront donc pas dans le cache alors que la plupart des tests présentés travaillent beaucoup en RAM.

    Les mesures d'écriture ne sont pas forcément pertinentes non plus, car les commandes rendent la main avant que les données soient effectivement sur disque. Sur une opération unitaire, pourquoi pas, mais si on enchaîne les traitements comme demandé ici, il risque d'y avoir une grosse contention disque.
    alors bon, vu d'ici pour moi c'est de la mauvaise foi top level, mais je ne suis peut-être pas objectif du tout, le mieux serait peut-être que tu fasses la batterie de tests qui va bien de ton côté, dont les résultats seront irréfutables et mettrons en évidence l'effet du copy-on-write dont tu parles sur la modification par dd d'1 chaine systématique de caractères dans plusieurs fichiers volumineux, et la "lourdeur" des écritures dans le contexte adhoc de la conversation et de la solution que je proposais

    donc pour rappel mon propos c'est de dire que dans le cadre de la solution que j'ai proposé, le grep est consommateur, mais l'écriture, fut-elle 200x"bouzin" à modifier, que ce soit dans un seul fichier ou dans plusieurs, ne prend quasi rien comme temps, et que par ailleurs quand bien même il s'agit d'une solution assez médiocre (toujours à cause du grep qui va à son terme) ça reste malgré tout une solution qui va plus de 2x plus vite que la solution initiale à base de sed -i, et ça je te le signe, que ce soit sur un fichier unique ou sur plusieurs

    "à vérifier" donc

  9. #29
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    j'imagine que tu parles du fichier temporaire dans le cadre de ta méthode (c'est à dire un bout de fichier uniquement), je parlais du fichier temporaire comme le fait un sed, c'est à dire en recopiant l'intégralité du fichier (c'est exactement ce que tu dis quelques lignes plus haut sur les 10mins dont parle Bouga74)
    Non, ce que je veux dire, c'est que d'une part écrire la totalité du fichier source dans un autre fichier, temporaire donc, puis renommer ce fichier avec le nom du fichier source, ou d'autre part écrire la totalité du fichier par dessus le même fichier comme le fait l'astucieux pipeline de zipe31 prennent un temps équivalent. Avec la solution basée sur "sed -i", le problème ne vient pas du fait qu'un fichier temporaire est utilisé mais entre autres du fait que sed fait un nombre très élevé de petites entrées/sorties en lecture comme en écriture, probablement de 4k.

    Citation Envoyé par BufferBob Voir le message
    oui si tu veux, le cache c'est très utile c'est vrai, et comme ça ne fonctionne qu'en lecture
    Le buffer-cache fonctionne aussi en écriture puisqu'on travaille ici en asynchrone, mais ton OS ne doit plus savoir où donner de la tête car le buffer cache est saturé...

    pour la petite info j'ai refais les mesures depuis ce matin, et effectivement la mesure sur le cp était faussée à l'arrivée (testé 3x chacun, en mettant le fichier en cache au préalable) je trouve toujours ~2min en lecture et 5min en écriture pour un fichier de 12G
    Sans lecture préalable (donc sans cache), tu devrais mettre entre 4 minute 30 et 5 minutes pour lire le fichier.

    Pour les écritures, il faut tenir compte du fait qu'elle n'est pas effective quand le programme te rends la main, d'ou le problème potentiel de saturation disque si tu enchaînes aussitôt une lecture pour traiter le fichier suivant.

    donc pour rappel mon propos c'est de dire que dans le cadre de la solution que j'ai proposé, le grep est consommateur, mais l'écriture, fut-elle 200x"bouzin" à modifier, que ce soit dans un seul fichier ou dans plusieurs, ne prend quasi rien comme temps, et que par ailleurs quand bien même il s'agit d'une solution assez médiocre (toujours à cause du grep qui va à son terme) ça reste malgré tout une solution qui va plus de 2x plus vite que la solution initiale à base de sed -i, et ça je te le signe, que ce soit sur un fichier unique ou sur plusieurs
    Oui, bien sûr, ça ira deux fois plus vite que le "sed -i".

    On ne s'est pas bien compris car tu n'avais pas bien lu le problème posé et de mon côté, j'ai mis un bout de temps à comprendre de quelle solution tu parlais car je n'avais pas vu ton "Edit"...
    ɹǝsn *sıɹɐlos*

  10. #30
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    bon ben du coup je les ai (re-)fais moi les tests, en synchronisant à chaque fois pour bien se rendre compte

    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
    $ du -h fichier*
    1,0G    fichier1
    2,0G    fichier2   # 2x fichier1
    4,0G    fichier3   # 2x fichier2 ou 4x fichier1
    8,0G    fichier4   # 2x fichier3 ou 4x fichier2 ou 8x fichier1
    2,0G    fichier5   # fichier2
    1,0G    fichier6   # fichier1
    1,0G    fichier7   # fichier1
    4,0G    fichier8   # fichier3
    $ head -1 fichier1 | sed -e 's/ /\n/g' | sort | uniq -c
        200 bouzin
          1 k1T84qYw0PqelaJ+laMqPAJyulfctTKALbanplQW5sJCXxDjXoc+yaaisf3WA9
    $ head -1 fichier* | sed -e 's/ /\n/g' | sort | uniq -c | head -4
          7 
          8 <==
          8 ==>
       1600 bouzin
    on a donc un set de 8 fichiers de tailles variables, de 1G à 8G, avec dans chacun -comme je suis mazo- non pas 1 mais 200 occurrences à remplacer, pour un total de 1600 occurrences

    ma solution toute pourrite, avec un sync au bout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # time { for fic in fichier*; do grep -boF "bouzin" ${fic} | cut -d':' -f1 | while read offset; do echo -ne "BOUZIN" | dd of=${fic} conv=notrunc bs=1 seek=${offset} 2>/dev/null; done; done; }
    real    4m38.305s
    # time sync
    real    0m0.719s
    la solution initiale à base de sed -i :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # time sed -i 's/bouzin/BOUZIN/g' fichier*
    real    20m40.090s
    # time sync
    real    0m0.592s
    et finalement, s'il n'y a qu'une seule occurrence à remplacer (conditions de l'énoncé) on pourrait demander à grep de stopper son traitement dès qu'il a réussit à matcher au moins 1 ligne, avec le switch -m1.
    il se trouve que mes fichiers contiennent chacun non pas 1 mais 200 occurrences à remplacer, mais elles sont toutes sur la même ligne (donc dans le même bloc du même secteur, qu'on va réécrire pleins de fois etc. etc.), on reste donc dans des conditions similaires, modulo la lourdeur des écritures évoquée plus avant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # time { for fic in fichier*; do grep -boF -m1 "bouzin" ${fic} | cut -d':' -f1 | while read offset; do echo -ne "BOUZIN" | dd of=${fic} conv=notrunc bs=1 seek=${offset} 2>/dev/null; done; done; }
    real    0m1.997s
    # time sync
    real    0m0.015s
    # head -1 fichier* | sed -e 's/ /\n/g' | sort | uniq -c | head -4
          7 
          8 <==
          8 ==>
       1600 BOUZIN
    on voit donc que :
    • quand on coupe le grep, finalement ne restent que les 1600 écritures, en une paire de secondes
    • le sync est immédiat, s'il y avait des écritures à synchroniser sur le disque, elles sont immédiates également, donc 1600 écritures en spawnant 1600 fois dd, ça prend walou
    • et finalement ma solution pourrie du départ était presque 5x plus rapide que la solution initiale du PO en l'état, en ajoutant le switch -m1 à grep et dans le contexte précis de l'énoncé ça devient même une solution qui tient bien la route et ne nécessite pas de savoir localiser la chaine à remplacer


    je m'arrête donc ici et part comme un prince

  11. #31
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    quand on coupe le grep, finalement ne restent que les 1600 écritures, en une paire de secondes
    Exact.

    le sync est immédiat, s'il y avait des écritures à synchroniser sur le disque, elles sont immédiates également, donc 1600 écritures en spawnant 1600 fois dd, ça prend walou
    C'est vrai, mais en réalité, grâce aux buffering des écritures asynchrones il n'y a guère plus d'une écriture physique par fichier. Toutes les explications que j'ai présenté ne sont en fait valables que pour des écritures synchrones. Mea culpa, je suis trop habitué aux écritures synchrones sur ce type de benchmark. Avec des écritures synchrones (ajout de oflag=sync à la commande dd), les deux secondes se transforment en quelque chose comme cinq minutes, et là, plus de doute, il faut optimiser le code !

    et finalement ma solution pourrie du départ était presque 5x plus rapide que la solution initiale du PO en l'état
    C'est vrai, mais celle que j'avais posté juste avant était quelque centaines voire milliers de fois plus rapide que la solution initiale ...

    en ajoutant le switch -m1 à grep et dans le contexte précis de l'énoncé ça devient même une solution qui tient bien la route et ne nécessite pas de savoir localiser la chaine à remplacer
    Exact, elle avait du potentiel ! :-)
    ɹǝsn *sıɹɐlos*

  12. #32
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    Avec des écritures synchrones (ajout de oflag=sync à la commande dd), les deux secondes se transforment en quelque chose comme cinq minutes
    toujours pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ time {
      for fic in fichier*; do
        grep -boF -m1 "bouzin" ${fic} | cut -d':' -f1 | while read offset; do
          echo -ne "BOUZIN" | dd of=${fic} conv=notrunc bs=1 oflag=sync seek=${offset} 2>/dev/null;
        done;
      done;
    }
    real    0m30.282s

  13. #33
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Bizarre, j'ai observé ces 5 minutes sur une machine où le reste des tests prenaient pourtant un temps similaire au tien, mais je n'ai fait qu'un test, il faudra que je revérifie. Cette différence s'explique peut-être par le matériel et/ou le système d'exploitation (type de système de fichier utilisé, de la taille des blocs disque, etc.). Chez toi, c'est quand même quinze fois plus lent que les deux secondes sans le oflag=sync.
    ɹǝsn *sıɹɐlos*

  14. #34
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    c'est quand même quinze fois plus lent que les deux secondes sans le oflag=sync.
    oui mais quel intérêt intéret de forcer un contexte désavantageux alors que celui par défaut fonctionne au poil ? (certainement pas d'avoir raison à tout prix en tous cas )

    par ailleurs c'est toujours 1600 occurrences à remplacer, si on s'en tient à 1 occurrence par fichier comme stipulé par l'énoncé c'est instantané

  15. #35
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    oui mais quel intérêt intéret de forcer un contexte désavantageux alors que celui par défaut fonctionne au poil ? (certainement pas d'avoir raison à tout prix en tous cas )
    Non, j'ai déjà reconnu que je m'était trompé pour cette partie. Le test sert juste à expliquer ce à quoi j'ai l'habitude d'être confronté. Activer les écritures synchrones n'a bien sûr aucun intérêt ici, mais ce n'est pas le cas pour certaines applications, genre financières où l'on doit être sûr qu'une opération terminée au niveau de l'application ne risque pas de ne pas se traduire par un changement persistant sur disque en cas de crash ou autre coupure intempestive.
    par ailleurs c'est toujours 1600 occurrences à remplacer, si on s'en tient à 1 occurrence par fichier comme stipulé par l'énoncé c'est instantané
    Oui, ce que je veux dire, c'est que les 1600 occurrences sont dans le même bloc donc peuvent ne correspondre qu'à une seule I/O physique après optimisation du buffer cache.
    ɹǝsn *sıɹɐlos*

  16. #36
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 242
    Points : 13 457
    Points
    13 457
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    oui mais quel intérêt intéret
    Pas compris. "Intérêt" n'existe pas sans circonflexe.

    Voir source
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  17. #37
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Oui, c'est un excès de zèle de BufferBob. Les médias ont parlé de disparition de l'accent circonflexe mais seuls les î et les û sont concernés.
    ɹǝsn *sıɹɐlos*

  18. #38
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    hihi oui, mais je ne suis pas pour, c'était plus un pied de nez qu'autre chose

    Citation Envoyé par jlliagre Voir le message
    mais seuls les î et les û sont concernés.
    ah ben j'aurais appris un truc

  19. #39
    Membre habitué
    Homme Profil pro
    Développeur
    Inscrit en
    Juin 2009
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2009
    Messages : 171
    Points : 172
    Points
    172
    Par défaut
    Sympa les débats ici !
    Il y a des spécialistes dans le coin en tout cas, ça fait plaisir.

    Juste pour préciser que la modification que je fais concernant les dates est uniquement lié à du test
    Mais vous m'avez fait gagné un paquet de temps dans tous les cas, mais c'est pour ça que je n'ai pas cherché une autre méthode de remplacement telle que discuté (script C ou autre).

    Encore merci !

  20. #40
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut
    Bah, plus haut, j'ai fourni un petit script "one-liner" perl qui fait aussi le boulot tel que le dd + sed + dd
    Cordialement.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Rechercher/remplacer, supprimer du texte
    Par Vinceoreste dans le forum Excel
    Réponses: 6
    Dernier message: 03/05/2018, 14h38
  2. Recherche/Remplacement dans un texte
    Par John Fullspeed dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 09/02/2013, 12h00
  3. Réponses: 8
    Dernier message: 12/11/2007, 10h16
  4. [RegEx] Remplacement rapide dans un fichier texte (RTF)
    Par johweb dans le forum Langage
    Réponses: 12
    Dernier message: 17/01/2007, 09h04
  5. Réponses: 4
    Dernier message: 12/10/2006, 17h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo