Čtení a parsování textového souboru

jpu

Čtení a parsování textového souboru
« kdy: 02. 08. 2017, 16:14:26 »
Zdravim vsetkych guru prispievatelov root.cz. Rad by som sa s nimi poradil ohladom jednej ulohy.
Mam velky(>3GB) textovy log subor. Ide o nejaky log subor, kam sa loguju veci pocas vykonavania programu. Zo suboru sa maju vycitat nejake veci, podla zadanych kriterii.

Povedzme ze mam vycitat vsetkych uzivatelov, ktori boli zadani na vstupe a potom k danym uzivatelom priradit veci, ktore sa ich tykaju.

Precitat samotne riadky suboru nie je zlozite a je to relativne rychle. Pouzivam na to File.ReadLines, ktora vracia IEnumerable. Horsie je to s vyhladavanim, to uz zaberie dlhsi cas, nakolko kazdy riadok sa musi porovnat voci trom regularnym vyrazom. Mne napadla taka varianta pouzit TPL Dataflow a implementacia producent/konzument.

Neviem o kolko by sa znizil vysledny cas oproti klasickemu rieseniu, ale za skusku clovek nic neda, akurat, ze toto riesenie mi bolo "zamietnute", resp. nedostal by som tolko casu realizovat to. Co si myslite?
« Poslední změna: 03. 08. 2017, 22:20:09 od Petr Krčmář »


gll

Re:Citanie a parsovanie zo suboru
« Odpověď #1 kdy: 02. 08. 2017, 16:55:53 »
nejlepšího zrychlení dosáhneš splitnutím toho souboru na několik bloků. Paralelizace na úrovni řádků nebývá moc účinná, tam je limitující IO.

na linuxu by to šlo treba takto

Kód: [Vybrat]
<big_file.txt parallel --pipe --block 200m ./tvuj_command

jpu

Re:Citanie a parsovanie zo suboru
« Odpověď #2 kdy: 02. 08. 2017, 17:26:47 »
Lenze neviem ako to splitnut, pretoze moze sa stat, ze to utnem zle a nebudu mi potom pasovat veci/udaje

gll

Re:Citanie a parsovanie zo suboru
« Odpověď #3 kdy: 02. 08. 2017, 17:33:29 »
Lenze neviem ako to splitnut, pretoze moze sa stat, ze to utnem zle a nebudu mi potom pasovat veci/udaje

gnu parallel splitne soubor podle delimiterů, nerozpůlí řádku.

jpu

Re:Citanie a parsovanie zo suboru
« Odpověď #4 kdy: 02. 08. 2017, 19:09:13 »
Pouzivam windows a robim to v C#. To na doplnenie :)


Kit

Re:Citanie a parsovanie zo suboru
« Odpověď #5 kdy: 02. 08. 2017, 20:12:16 »
Pouzivam windows a robim to v C#. To na doplnenie :)

Dobře ti tak :)

jpu

Re:Citanie a parsovanie zo suboru
« Odpověď #6 kdy: 02. 08. 2017, 20:26:30 »
Citace
Dobře ti tak :)
Dik za radu :)

gll

Re:Citanie a parsovanie zo suboru
« Odpověď #7 kdy: 02. 08. 2017, 20:52:09 »
Pouzivam windows a robim to v C#. To na doplnenie :)

zkusil jsi neco takoveho? Velikost chunku musí být menší, protože se musí vejít  do paměti

Kód: [Vybrat]
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;


public static class Hello3
{
    public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
                                                                   this IEnumerable<TSource> source,
                                                                   int batchSize)
    {
        var batch = new List<TSource>();
        foreach (var item in source)
        {
            batch.Add(item);
            if (batch.Count == batchSize)
            {
                yield return batch;
                batch = new List<TSource>();
            }
        }

        if (batch.Any()) yield return batch;
    }

   public static void Main(string[] args)
   {
       int lc = 0;
       Parallel.ForEach(File.ReadLines("big_file.txt").Batch(5000),
                        new ParallelOptions { MaxDegreeOfParallelism = 12 },
                        (chunk, _, chunkNum) =>
               {
                   foreach(string line in chunk) {
                        // zpracuj radku
                   };
               });
   }
}

podle me tady jen trolis. Kdybys opravdu potreboval pomoc, tak se neptas na linuxovem foru.


Honza

Re:Citanie a parsovanie zo suboru
« Odpověď #8 kdy: 02. 08. 2017, 21:04:24 »
Pro vyhledávání v celém souboru se jeho celému přečtení nevyhneš. Můžeš to nasypat do databáze a tam to pak vyhledávat.
Ale hádám, že nejčastější use-case bude vyhledávání dle času, nějaký interval od-do. Pak můžeš při prvním přečtení souboru si udělat vlastní index časových značek+offsetů v daném souboru. Tam můžeš jednoduše uložit jen offset začátku řádků. Potom vyhledáváš klasicky sekvenčně, ale pouze v požadovaném úseku offset1->offset2, ne v celém souboru.
Dokonce i update toho indexu, když přibudou další řádky můžeš dělat už jen přírustkově.

Pro vyhledávání regulárních výrazů v celém souboru se dá jednoduše ten celý soubor předzpracovat tak, aby to hledání pak mělo složitost pouze logaritmickou. Doporučuji něco o nich nastudovat.

PS: obejdeš se tak bez paralelního zpracování, bude to efektivnější

gll

Re:Citanie a parsovanie zo suboru
« Odpověď #9 kdy: 02. 08. 2017, 21:08:42 »
Pro vyhledávání v celém souboru se jeho celému přečtení nevyhneš. Můžeš to nasypat do databáze a tam to pak vyhledávat.
Ale hádám, že nejčastější use-case bude vyhledávání dle času, nějaký interval od-do. Pak můžeš při prvním přečtení souboru si udělat vlastní index časových značek+offsetů v daném souboru. Tam můžeš jednoduše uložit jen offset začátku řádků. Potom vyhledáváš klasicky sekvenčně, ale pouze v požadovaném úseku offset1->offset2, ne v celém souboru.
Dokonce i update toho indexu, když přibudou další řádky můžeš dělat už jen přírustkově.

Pro vyhledávání regulárních výrazů v celém souboru se dá jednoduše ten celý soubor předzpracovat tak, aby to hledání pak mělo složitost pouze logaritmickou. Doporučuji něco o nich nastudovat.

PS: obejdeš se tak bez paralelního zpracování, bude to efektivnější

Mluvit o logaritmické složitosti v souvisloslosti s paralelizací je nesmysl. Nejde o přečtení souboru, ale provádění operace s řádky. To se dá paralelizovat.

gll

Re:Citanie a parsovanie zo suboru
« Odpověď #10 kdy: 02. 08. 2017, 21:10:15 »
Mluvit o logaritmické složitosti

*asymptotické složitosti

jpu

Re:Citanie a parsovanie zo suboru
« Odpověď #11 kdy: 02. 08. 2017, 21:34:14 »
gll:
preco by som trollil? normalne sa pytam. Chcel som sa len poradit...Myslim, ze je tu dost tem, kam sa chodi trollovat

jpu

Re:Citanie a parsovanie zo suboru
« Odpověď #12 kdy: 02. 08. 2017, 21:37:18 »
Pro vyhledávání v celém souboru se jeho celému přečtení nevyhneš. Můžeš to nasypat do databáze a tam to pak vyhledávat.
Ale hádám, že nejčastější use-case bude vyhledávání dle času, nějaký interval od-do. Pak můžeš při prvním přečtení souboru si udělat vlastní index časových značek+offsetů v daném souboru. Tam můžeš jednoduše uložit jen offset začátku řádků. Potom vyhledáváš klasicky sekvenčně, ale pouze v požadovaném úseku offset1->offset2, ne v celém souboru.
Dokonce i update toho indexu, když přibudou další řádky můžeš dělat už jen přírustkově.

Pro vyhledávání regulárních výrazů v celém souboru se dá jednoduše ten celý soubor předzpracovat tak, aby to hledání pak mělo složitost pouze logaritmickou. Doporučuji něco o nich nastudovat.

PS: obejdeš se tak bez paralelního zpracování, bude to efektivnější

Mluvit o logaritmické složitosti v souvisloslosti s paralelizací je nesmysl. Nejde o přečtení souboru, ale provádění operace s řádky. To se dá paralelizovat.
ano, ide mi skor o operacie tykajuce sa spracovania riadkov, pretoze to trva najdlhsie

gll

Re:Citanie a parsovanie zo suboru
« Odpověď #13 kdy: 02. 08. 2017, 21:42:37 »
gll:
preco by som trollil? normalne sa pytam. Chcel som sa len poradit...Myslim, ze je tu dost tem, kam sa chodi trollovat

právě, že jsem často četl tvé příspěvky v tématech linux vs windows. Možná jsem tě neprávem podezříval z pokusu o založení dalšího flame tématu. V tom případě se omlouvám.

Honza

Re:Citanie a parsovanie zo suboru
« Odpověď #14 kdy: 02. 08. 2017, 22:08:37 »
Mluvit o logaritmické složitosti v souvisloslosti s paralelizací je nesmysl. Nejde o přečtení souboru, ale provádění operace s řádky. To se dá paralelizovat.
Ale to bylo špatně pochopeno, měl jsem namysli, že to zpracování lze urychlit i bez té paralelizace, paralelní zpracování lze samozřejmě použít i potom...