Samojen stringien poisto stringlistista

Anonyymi

Minulla on kaksi stringlistia. Ensimmäisessä stringlistissa (stringlist1) on 500 000 stringia. Toisessa stringlistissa (stringlost2) on 1500000 stringia. Ensimmäisen listan stringit on toisen stringlistan stringien osajoukko. Olen yrittänyt tehdä algoritmia ja silmukkaa jolla poistaisin stringlist1:ssa esiintyvät stringit stringlist2:sta jolloin siis stringlist2:een jäisi miljoona stringiä.

Ongelma on tuhoton hitaus. Tein algoritmin delphilla:

For i:=0 to stringlist1.count do Stringlist2.delete(stringlist2[indexOf(stringlist1[i]]);

Jolloin se looppaa 1.5 miljoonaa kertaa stringlist1:n läpi mikä ei ole tuhottoman hidasta. Hitaus ilmeisesti tulee kun se vertaa jokaisen kohdalla mistä kohtaa stringlist2:ta se stringi löytyy, mikä sen indeksi on jotta sw tietää tuhota oikean stringin. En tiedä miten delphi 10.3 tämän haun toteuttaa oletuksena. Listit on periaatteessa sortattu ohjelman ulkopuolella, tosin en tiedä miten tietokone tämän sorttauksen tulkitsee koska jokaisessa stringissä on sekä numeroita että kirjaimia (13 merkkiä kussakin).

Mikä algoritmi voisi nopeuttaa tätä vai voisko mikään? Auttaisko jotenkin vertailla stringin ekoja merkkejä ja koittaa jakaa stringlist2:ta osiin ja tutkia missä osassa stringi siellä on jotta täytyisi käydä läpi pienempää listia? Tosin tuleehan siinä sit ne if-lauseet. Vai voisiko koko roskan toteuttaa muussa muodossa kuin stringlist? Joku dictionary jossa on nopeampi haku? Miten se toreutettas 15 merkin stringeillä?

39

<50

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Anonyymi

      Luo kokonaan uusi list3 kahlaten list1:stä sen mukaan löytyykö sille tupla list2:ssa.

    • Anonyymi
    • Anonyymi

      Jos stringisi ovat järjestyksessä, sitä voidaan kyllä nopeuttaa huomattavasti (ja noin isoilla listoilla on luultavasti tehokkaampaa järjestää (O(n*log(n)) listat ensin, ja sen jälkeen poistaa ylimääräiset stringit järjestetyistä listoista (O(n)), kuin suoraan lähteä poistamaan stringejä satunnaisjärjestyksessä (O(n^2)).

      Jos jostain syystä haluat säilyttää stringien alkuperäisen järjestyksen, niin ei sitä oikein voi tuosta O(n^2):sta parantaa.

      • Anonyymi

        Voihan sen järjestyksen ensin tallentaa, sitten tehdä järjestystavalla ja lopuksi järjestää uudelleen tallennetun järjestyksen avulla.


      • Anonyymi
        Anonyymi kirjoitti:

        Voihan sen järjestyksen ensin tallentaa, sitten tehdä järjestystavalla ja lopuksi järjestää uudelleen tallennetun järjestyksen avulla.

        No se on totta.


      • Anonyymi

        Sellainen lisähuomio vielä, että yleensä kannattaa miettiä myös pidemmällä tähtäimellä, mitä haluaa ohjelmissaan tehdä. Jos poimit kolmasosan string-listastasi toiseen listaan ja haluat poistaa ne sitten alkuperäisestä listasta, niin nuo molemmat kannattaa tehdä samalla kertaa (ellei ole jotain syytä, miksi niin ei voisi tehdä). Eli samalla kun lisäät stringlist2:een stringin, poista se stringlist1:stä. Silloin et joudu käymään listoja läpi yhtäkään ylimääräistä kertaa.


      • Anonyymi
        Anonyymi kirjoitti:

        No se on totta.

        Ei ubuntussa tarvitse stringlistissa, se toimii ilmankin.


    • Anonyymi

      Eikö täällä ole enää muita kuin ubuntun käyttäjiä.

    • Anonyymi

      sudo apt install meld && meld
      tai heti komennolla: diff stringlist1 stringlist2

      • Anonyymi

        Ei tässä haettu samaa asiaa jonkun toisen koodaamana, vaan tehokkaampaa tapaa tehdä se.


      • Anonyymi

        meld tekee yhdistelmä listoja, ei mitään apua tässä tehtävässä.


      • Anonyymi

        diff on meld työkaluun nähden käänteinen, ja siitä olisi apua, mutta tulostus täytyisi siistiä.


    • Anonyymi

      Mikään hakualgoritmit, lajittelualgoritmit tai valinta-algoritmit muutokset eivät merkittävästi nopeuta käsittelyä.

      Käsittelyn ajaksi katkaistu yhteys graafisen komponentin tilanpäivityksiin nopeuttaa.

      Myös käsittelyn luovuttaminen ulkoiselle komennoille (diff: suosittelen) nopeuttaa merkittävästi. Useita minuutteja vievä lajittelu, on valmis alle 2 sekunnin.

      • Anonyymi

        Ehdottomasti kaikki ylimääräinen grafiikka kannattaa riisua, ja sillä voi olla yllättävänkin suuri vaikutus. Riittävän isolla datamäärällä (miljoona riviä on jo varsin paljon) algoritmin valinta on kuitenkin ylivoimaisesti merkittävin tekijä.

        Jos n = 1 000 000, niin O(n^2)-algoritmi, vie noin biljoona aikayksikköä, kun taas O(n*log(n)) vie vain kymmenen miljoonaa aikayksikköä, eli aikavaativuus putoaa sadastuhannesosaan vaihtamalla tehokkaampaan algoritmiin.


      • Anonyymi

        Esimerkkinä lajittelusta, jossa 559 610 (yli puoli miljoonaa) merkkijonoa lajitella pituusjärjestykseen (pisin viimeiseksi), vie hiukan yli puoli sekuntia (real 0,630s).

        Tulos saavutetaan kun lajittelu ulkoistetaan cat, awk, sort ja cut komentojen yhteiseksi tehtäväksi.


      • Anonyymi
        Anonyymi kirjoitti:

        Esimerkkinä lajittelusta, jossa 559 610 (yli puoli miljoonaa) merkkijonoa lajitella pituusjärjestykseen (pisin viimeiseksi), vie hiukan yli puoli sekuntia (real 0,630s).

        Tulos saavutetaan kun lajittelu ulkoistetaan cat, awk, sort ja cut komentojen yhteiseksi tehtäväksi.

        Aivan riippumatta siitä, miten sen käytännössä toteutat (itse koodaten vai muiden palikoilla leikkien), algoritmi on se, millä on väliä. Jos käsittelet miljoonan rivin datan O(n^2)-algoritmilla, se vie (noin) sata tuhatta kertaa kauemmin kuin O(n*log(n))-algoritmilla.


      • Anonyymi

        Keksin että yksi avainsana oli binary search. En ole vielä tarkastanut toimiiko se oikein mutta Delphin TStringList.Find käyttää binääristä hakua kun IndexOf käytti lineaarista. Ensin TStringList.sort niin StringList sortataan (en tiedä miten se konekielitasolla menee kuin 15 merkin jono sortataan). Tämän jälkeen Find funktio palauttaa index-parametrina poistettavan stringin indeksin toisella listilla jotta se voidaan deletoita. Näyttää tunnin algoritmi putoavan muutamaan minuuttiin.

        Muita vaihtoehtoja voisi olla kuulemma järjestysluvullinne array. Pitäisi päästä vertailemaan järjestyslukuja, jolloin se olisi yksi komento tai yksi kohta muistissa, ei vertailemaan 15 merkin merkkijonona. Joku hash list, dictionary tai joku. Tehostuisi ehkä vielä suhteessa binäärihakuun.


      • Anonyymi
        Anonyymi kirjoitti:

        Keksin että yksi avainsana oli binary search. En ole vielä tarkastanut toimiiko se oikein mutta Delphin TStringList.Find käyttää binääristä hakua kun IndexOf käytti lineaarista. Ensin TStringList.sort niin StringList sortataan (en tiedä miten se konekielitasolla menee kuin 15 merkin jono sortataan). Tämän jälkeen Find funktio palauttaa index-parametrina poistettavan stringin indeksin toisella listilla jotta se voidaan deletoita. Näyttää tunnin algoritmi putoavan muutamaan minuuttiin.

        Muita vaihtoehtoja voisi olla kuulemma järjestysluvullinne array. Pitäisi päästä vertailemaan järjestyslukuja, jolloin se olisi yksi komento tai yksi kohta muistissa, ei vertailemaan 15 merkin merkkijonona. Joku hash list, dictionary tai joku. Tehostuisi ehkä vielä suhteessa binäärihakuun.

        Mitkään hakualgoritmit, lajittelualgoritmit tai valinta-algoritmit eivät ole varteen otettavia vaihtoehtoja, huippuunsa viritetylle ja juuri tätä tehtävää varten luodulle ulkoiselle komennolle.

        Vai mitä olet mieltä, kun suoritamme "kai" -merkkijono haun, tiedostosta, joka sisältää yli puoli miljoonaa erilaista merkkijonoa, ja suoritus vie vain 0,017s, tuottaen tiedoston jossa on 5 917 löytynyttä.

        Ei tätä voi nopeuttaa millään, siispä opettelemme ulkoistamaan tehtäviä tausta suorituksena. Ellet vielä osaa, nyt on korkea aika opetella.


      • Anonyymi
        Anonyymi kirjoitti:

        Mitkään hakualgoritmit, lajittelualgoritmit tai valinta-algoritmit eivät ole varteen otettavia vaihtoehtoja, huippuunsa viritetylle ja juuri tätä tehtävää varten luodulle ulkoiselle komennolle.

        Vai mitä olet mieltä, kun suoritamme "kai" -merkkijono haun, tiedostosta, joka sisältää yli puoli miljoonaa erilaista merkkijonoa, ja suoritus vie vain 0,017s, tuottaen tiedoston jossa on 5 917 löytynyttä.

        Ei tätä voi nopeuttaa millään, siispä opettelemme ulkoistamaan tehtäviä tausta suorituksena. Ellet vielä osaa, nyt on korkea aika opetella.

        Millä taikuudella sinä luulet niiden komentojen toimivan? Algoritmi on siellä taustalla joka tapauksessa, ja toki sellainen komento johon on käytetty järkevää algoritmia, kannattaa valita, mutta kyse on silti täsmälleen samasta asiasta: haluatko käyttää tehokkaampaa vai vähemmän tehokasta algoritmia.

        Jos et itse osaa ajatella asiaa, joudut luottamaan sokeasti siihen, että juuri se sinun valitsemasi komento on sattumalta tehty tähän nimenomaiseen tapaukseen järkevällä algoritmilla. Jos osaat ajatella, voit toki käyttää satunnaista komentoa jos laiskottaa, tai sitten voit miettiä, mikä algoritmi on kyseiseen tehtävään paras, ja käyttää sitä, joko itse koodattuna tai jostain valmiista paketista löydettynä.


      • Anonyymi
        Anonyymi kirjoitti:

        Ehdottomasti kaikki ylimääräinen grafiikka kannattaa riisua, ja sillä voi olla yllättävänkin suuri vaikutus. Riittävän isolla datamäärällä (miljoona riviä on jo varsin paljon) algoritmin valinta on kuitenkin ylivoimaisesti merkittävin tekijä.

        Jos n = 1 000 000, niin O(n^2)-algoritmi, vie noin biljoona aikayksikköä, kun taas O(n*log(n)) vie vain kymmenen miljoonaa aikayksikköä, eli aikavaativuus putoaa sadastuhannesosaan vaihtamalla tehokkaampaan algoritmiin.

        Poistin ruudulle tulostettan laskurin arvon joka siis käy yhdestä puoleentoistamiljoonaan ja nyt ei tulostu mitään tietoa missä mennään niin ohjelma nopeutui 40 minuutista 4 minuuttiin. Näyttäs toimivan. Mietityttää vaan voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle? Vai pakko olla bugi? Mut toistaalta laitoin vain kommenttimerkit yhden rivin eteen.


      • Anonyymi
        Anonyymi kirjoitti:

        Millä taikuudella sinä luulet niiden komentojen toimivan? Algoritmi on siellä taustalla joka tapauksessa, ja toki sellainen komento johon on käytetty järkevää algoritmia, kannattaa valita, mutta kyse on silti täsmälleen samasta asiasta: haluatko käyttää tehokkaampaa vai vähemmän tehokasta algoritmia.

        Jos et itse osaa ajatella asiaa, joudut luottamaan sokeasti siihen, että juuri se sinun valitsemasi komento on sattumalta tehty tähän nimenomaiseen tapaukseen järkevällä algoritmilla. Jos osaat ajatella, voit toki käyttää satunnaista komentoa jos laiskottaa, tai sitten voit miettiä, mikä algoritmi on kyseiseen tehtävään paras, ja käyttää sitä, joko itse koodattuna tai jostain valmiista paketista löydettynä.

        Käyttöjärjestelmän komennot (grep) kuten tuossa edellisessä oli on vuosien työn tulos, jota hiotaan aina vain paremmaksi. Minä en luota omiin enkä sinun kykyihin tuottaa tehokkaampaa kuin olemassa olevat komennot jo on.

        Myöskään itse komennon käyttämä algoritmi ei kiinnosta, riittää että on tehokas ja toimii. On erittäin tyhmää keksiä pyörä joka kerta uudestaan, kun vielä ottaa huomioon se tosiasian että itse tehtynä siitä tulisi merkittävästi huonompi, ja toteuttaminen veisi useita vuosia.


      • Anonyymi
        Anonyymi kirjoitti:

        Käyttöjärjestelmän komennot (grep) kuten tuossa edellisessä oli on vuosien työn tulos, jota hiotaan aina vain paremmaksi. Minä en luota omiin enkä sinun kykyihin tuottaa tehokkaampaa kuin olemassa olevat komennot jo on.

        Myöskään itse komennon käyttämä algoritmi ei kiinnosta, riittää että on tehokas ja toimii. On erittäin tyhmää keksiä pyörä joka kerta uudestaan, kun vielä ottaa huomioon se tosiasian että itse tehtynä siitä tulisi merkittävästi huonompi, ja toteuttaminen veisi useita vuosia.

        Näistä tehoja vaativien tehtävien ulkoistamisesta, graafisen liittymän ulkopuolelle, on sekin hyöty että prosessien suoritus säikeisettään ja silloin tehtävä annetaan ytimelle, jolla sillä hetkellä on vähiten kuormaa.


      • Anonyymi
        Anonyymi kirjoitti:

        Käyttöjärjestelmän komennot (grep) kuten tuossa edellisessä oli on vuosien työn tulos, jota hiotaan aina vain paremmaksi. Minä en luota omiin enkä sinun kykyihin tuottaa tehokkaampaa kuin olemassa olevat komennot jo on.

        Myöskään itse komennon käyttämä algoritmi ei kiinnosta, riittää että on tehokas ja toimii. On erittäin tyhmää keksiä pyörä joka kerta uudestaan, kun vielä ottaa huomioon se tosiasian että itse tehtynä siitä tulisi merkittävästi huonompi, ja toteuttaminen veisi useita vuosia.

        Totta kai yksittäinen komento on (yleensä) optimoitu suurin piirtein niin tehokkaaksi kuin mahdollista. Jos sellainen on tarjolla siihen tehtävään, joka sinun pitäisi saada aikaan, se on todennäköisesti paras vaihtoehto.

        Mutta tosiasia on kuitenkin se ettei joka ikiselle asialle, minkä joku joskus voisi kuvitella haluavansa tietokoneella tehdä, ole olemassa omaa yksittäistä komentoa, ja heti kun ketjutat edes kaksi (saati sitten useampia) komentoa, sinä luot uuden algoritmin, jonka palaset kyllä ovat tehokkaita, mutta kokonaisuus voi olla äärimmäisen typerä ja tehoton jos et yhtään osaa ajatella algoritmisesti. Jos valikoit nuo tehokkaat komennot niin, että lopputulos on O(n^2)-algoritmi, se on riittävän isolla datalla väistämättä huonompi ratkaisu kuin tehottomalla tavalla itse koodattu O(n*log(n))-algoritmi. Toki vielä parempi on jos osaat miettiä tehokkaiden komentojen käytön niin, että saat niillä toteutettua sen O(n*log(n))-algoritmin.


      • Anonyymi
        Anonyymi kirjoitti:

        Ehdottomasti kaikki ylimääräinen grafiikka kannattaa riisua, ja sillä voi olla yllättävänkin suuri vaikutus. Riittävän isolla datamäärällä (miljoona riviä on jo varsin paljon) algoritmin valinta on kuitenkin ylivoimaisesti merkittävin tekijä.

        Jos n = 1 000 000, niin O(n^2)-algoritmi, vie noin biljoona aikayksikköä, kun taas O(n*log(n)) vie vain kymmenen miljoonaa aikayksikköä, eli aikavaativuus putoaa sadastuhannesosaan vaihtamalla tehokkaampaan algoritmiin.

        Koska kysymys on "yleistä ohjelmoinnista" -palstalla, se ei ota kantaa ohjelmointikieleen.

        Delphissä:

        Kannattaa huomata:

        type
        TStringList = class(TStrings)
        ...
        end;

        ja myös:

        TMemoStrings = class(TStrings)
        ...
        end;

        TListBoxStrings = class(TStrings)
        ...
        end;

        nuo TMemoStrings ja TListBoxStrings ovat siis sinänsä ihan oikeita tyyppejä, mutta referenssit noihin ovat usein tyy ppiä TStrings .

        siis esim:

        var
        SL : TStrings;

        SL := Memo1.Strings;

        ShowMessage(SL.Classname); // tulostaa "TMemoStrings"

        SL := ListBox1.Items;

        ShowMessage(SL.Classname); // tulostaa "TListBoxStrings"

        Mitään hitaita operaatioita EI PIDÄ koskaan suorittaa suoraan TMemoStrings eikä TListBoxStrings -luokkien objekteille !

        Jos hitaita operaatioita tarvitaan, suorita ne aina TStringList -luokan ilmentymälle eli objektille.

        Lisäksi:

        delete() on periaatteessa hidas operaatio, ja mitä lähempänä listan alkua poistettava merkkijono on, sitä hitaampi operaatio.

        siis kannattaa mieluummin tehdä for i := SL.Count-1 downto 0 -silmukka.

        Myös Sort() -operaatio muuttuu hitaaksi, jos listassa on satoja tuhansia merkkijonoja (tai jopa yli miljoona),

        Jos listassa on vaikkapa katuosoitteita (siis alkaa kadun nimellä) niin kannattaa jakaa kukin alkukirjain erikseen ja tehdä useita TStringList -objekteja, yksi kullekin alkukirjaimelle. Kannattaa samalla harkita, kuinka haluaa käsitellä isot/pienet kirjaimet.

        Olisi muuten testaamisen arvoinen asia:
        Onko delete() tai insert() -operaatio nopeampi "linked list" -toteutuksessa verrattuna Delphin TStringList -luokan käyttämään toteutukseen ?

        Muistioperaationa on nopeampi, mutta tietyn kohdan etsiminen muuttuu samalla hitaammaksi.

        Onkohan kukaan keksinyt hybriditietorakennetta, jolla saataisiin taulukon ja "linked LIST" -ratkaisujen parhaat puolety yhdistettyä ?


      • Anonyymi
        Anonyymi kirjoitti:

        Aivan riippumatta siitä, miten sen käytännössä toteutat (itse koodaten vai muiden palikoilla leikkien), algoritmi on se, millä on väliä. Jos käsittelet miljoonan rivin datan O(n^2)-algoritmilla, se vie (noin) sata tuhatta kertaa kauemmin kuin O(n*log(n))-algoritmilla.

        "Jos käsittelet miljoonan rivin datan O(n^2)-algoritmilla, se vie (noin) sata tuhatta kertaa kauemmin kuin O(n*log(n))-algoritmilla."

        Peraatetasolla varmaan ihan totta.

        Käytännön huomioina silti:

        1. ONKO tuo log(n) millainen logaritmi? Siis 10-kantainen, 2-kantainen vai ns. luonnollinen logaritmi, jossa kantalukuna on ns. neperin luku, jota merkitään yleensä symbolilla e ?

        2. QuickSort -algoritmia monet pitävät nopeana.
        Mutta onko kyseinen algoritmi kuitenkaan se paras (ja jos on, onko siitä useita erilaisia toteutuksia, jotka eroavat huomattavasti nopeudeltaan) ?

        2a) omia kokemuksia:
        QuickSort -algoritmi on suhteellisen nopea, jos lajiteltavia alkioita on enintään 100.000 (sata tuhatta). Tätä suuremmilla määrillä QäuickSort -algoritmi voi osoittautua yllätt
        vän hitaaksi !

        2b) Netistä luettua: QuickSort -algoritmi on erityisen hidas silloin, jos lähtöaineisto on jo ennestään melkein lajiteltu, mutta siellä on muutamia yksittäisiä alkioita, jotka ovat väärässä järjestyksessä.

        Voi hyvin olla, että USEIMMISSA tapauksissa QuickSort -algoritmi on nopein vaihtoehto.

        ENTÄ, jos algoritmit pisteytetään nopeuden mukaan siten, että kullekin algoritmille annetaan lajiteltavaksi sellainen lähtöaineisto, että kukin algoritmi suoriutuu hitaimmalla mahdollisella tavalla?

        Eli verrataan kutakin algoritmia vertaillaan nimenomaan kyseiselle algoritmille omin aisen ns. "worst case" -tapauksen mukaan.

        Mikä on tällöin paras algoritmi lajitteluun (oletetaan aineiston kooksi 2 miljoonaa merkkijonoa ja jakaumaksi kullekin algoritmille sellainen, josta on tiedossa, että moinen järjestysjakauma erityisesti hidastaa ko. algoritmia) ?


      • Anonyymi
        Anonyymi kirjoitti:

        Keksin että yksi avainsana oli binary search. En ole vielä tarkastanut toimiiko se oikein mutta Delphin TStringList.Find käyttää binääristä hakua kun IndexOf käytti lineaarista. Ensin TStringList.sort niin StringList sortataan (en tiedä miten se konekielitasolla menee kuin 15 merkin jono sortataan). Tämän jälkeen Find funktio palauttaa index-parametrina poistettavan stringin indeksin toisella listilla jotta se voidaan deletoita. Näyttää tunnin algoritmi putoavan muutamaan minuuttiin.

        Muita vaihtoehtoja voisi olla kuulemma järjestysluvullinne array. Pitäisi päästä vertailemaan järjestyslukuja, jolloin se olisi yksi komento tai yksi kohta muistissa, ei vertailemaan 15 merkin merkkijonona. Joku hash list, dictionary tai joku. Tehostuisi ehkä vielä suhteessa binäärihakuun.

        Delphin TStringList:

        Tuo binäärihakua käyttävä toimii oikein vain, jos Sorted = True.

        Toisaalta esim. insert ja add saattavat olla hitaampia, jos Sorted = True.

        Jouduin joskus itse lajittelemaan Delphin TStringList -luokan objektin, jossa oli satojatuhansia merkkijonoja (kukin alkoi kadun nimellä).

        Delphin oma Sort -metodi (tai Sorted := True) olivat hyvin hitaita.

        Päädyin jakamaan nuo kadun nimet 29 eri TStringList -luokan objektiksi, eli ensimmäiseen tuli "A" -kirjaimella alkavat kadunnimet ja viimeiseen "Ö" -kirjaimella alkavat kadunnimet.

        Sitten kullekin TStringList -luokan objektille oma erillinen Sort -metodikutsu.

        Tämä tapa oli huomattavasti nopeampi kuin koko pitkän listan lajittelu kerralla.


      • Anonyymi
        Anonyymi kirjoitti:

        Poistin ruudulle tulostettan laskurin arvon joka siis käy yhdestä puoleentoistamiljoonaan ja nyt ei tulostu mitään tietoa missä mennään niin ohjelma nopeutui 40 minuutista 4 minuuttiin. Näyttäs toimivan. Mietityttää vaan voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle? Vai pakko olla bugi? Mut toistaalta laitoin vain kommenttimerkit yhden rivin eteen.

        "voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle"

        Kyllä voi ja usein onkin !

        Jos silti haluat tiedon ruudulle, tee se fiksusti !

        esim näin:

        Työsäie (periytetty TThread -luokasta)

        päivittää muuttujaa, joka ilmaisee joko valmistumisasteen prosentteina, tai sitten (vieläkin nopeampi) läpikäydyn kappalemäärän ja kokonaiskappalemäärä toiseen muuttujaan.

        Jos muuttujat on määritelty globaalisti näin:

        var
        LapiKayty : Longword;
        KokonaisKPLMaara : Longword;

        niin silloin voi GUI -säikeeseen tehdä vaikkapa formilla olevalla TTimer -komponentilla (Interval = 250) OnTimer -käsittelijän, joka lukee molemmat muuttujat paikallisiin kopioihin näin:

        var
        A,B : Longword;
        PerCent : Double;
        S, S1 : String;

        begin
        A := LapiKayty;
        B := KokonaisKPLMaara;

        PerCent := LapiKayty * 100.0 / KokonaisKPLMaara;

        Str(PerCent:5:1, S1);

        S := S1 ' % läpikäyty';

        lblProgress.Caption := S;
        lblProgress.Repaint;

        end;

        Teoriassa tuossa kuuluisi lukita nuo muuttujat LapiKayty ja KokonaisKPLMaara (ks. TCriticalSection), mutta koska ne molemmat ovat CPU -rekisterin kokoisia (32 bit) ja ovat muistissa 4:LLÄ jaollisessa osoitteessa, niin tuosta syystä tuo lukitseminen ei ole ihan niin pakollista kuin moni luulee.

        Jos haluaa olla ihan 100% varma, ettei eri säikeet aiheuta konfliktia keskenään, niin ks. myös:

        InterlockedExchangeAdd ja InterlockedIncrement .

        Siis työsäie voisi kasvattaa LapiKayty :
        InterlockedIncrement (LapiKayty );

        Ja GUI -säie voisi lisätä arvoon LapiKayty vakion nolla, ja napata tuloksen talteen:
        InterlockedExchangeAdd (LapiKayty , 0)

        JOS tuo viimeinen antaa käännösvirheen, niin korjaa näin:
        InterlockedExchangeAdd (@LapiKayty , 0)

        Tuolla tavalla hidas näytön päivitys tehdään vain 4 kertaa sekunnissa sensijaan, että se tehtäisiin jokaisen alkion kohdalla (mikä olisi todella hidasta).


      • Anonyymi
        Anonyymi kirjoitti:

        "voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle"

        Kyllä voi ja usein onkin !

        Jos silti haluat tiedon ruudulle, tee se fiksusti !

        esim näin:

        Työsäie (periytetty TThread -luokasta)

        päivittää muuttujaa, joka ilmaisee joko valmistumisasteen prosentteina, tai sitten (vieläkin nopeampi) läpikäydyn kappalemäärän ja kokonaiskappalemäärä toiseen muuttujaan.

        Jos muuttujat on määritelty globaalisti näin:

        var
        LapiKayty : Longword;
        KokonaisKPLMaara : Longword;

        niin silloin voi GUI -säikeeseen tehdä vaikkapa formilla olevalla TTimer -komponentilla (Interval = 250) OnTimer -käsittelijän, joka lukee molemmat muuttujat paikallisiin kopioihin näin:

        var
        A,B : Longword;
        PerCent : Double;
        S, S1 : String;

        begin
        A := LapiKayty;
        B := KokonaisKPLMaara;

        PerCent := LapiKayty * 100.0 / KokonaisKPLMaara;

        Str(PerCent:5:1, S1);

        S := S1 ' % läpikäyty';

        lblProgress.Caption := S;
        lblProgress.Repaint;

        end;

        Teoriassa tuossa kuuluisi lukita nuo muuttujat LapiKayty ja KokonaisKPLMaara (ks. TCriticalSection), mutta koska ne molemmat ovat CPU -rekisterin kokoisia (32 bit) ja ovat muistissa 4:LLÄ jaollisessa osoitteessa, niin tuosta syystä tuo lukitseminen ei ole ihan niin pakollista kuin moni luulee.

        Jos haluaa olla ihan 100% varma, ettei eri säikeet aiheuta konfliktia keskenään, niin ks. myös:

        InterlockedExchangeAdd ja InterlockedIncrement .

        Siis työsäie voisi kasvattaa LapiKayty :
        InterlockedIncrement (LapiKayty );

        Ja GUI -säie voisi lisätä arvoon LapiKayty vakion nolla, ja napata tuloksen talteen:
        InterlockedExchangeAdd (LapiKayty , 0)

        JOS tuo viimeinen antaa käännösvirheen, niin korjaa näin:
        InterlockedExchangeAdd (@LapiKayty , 0)

        Tuolla tavalla hidas näytön päivitys tehdään vain 4 kertaa sekunnissa sensijaan, että se tehtäisiin jokaisen alkion kohdalla (mikä olisi todella hidasta).

        "PerCent := LapiKayty * 100.0 / KokonaisKPLMaara;"

        siis piti olla:

        PerCent := A* 100.0 / B;

        Eli käytä laskemiseen paikallisia kopioita muuttujista !


    • Anonyymi

      Mie oon maailman luokan ammattilainen stringien riisumisessa.

      • Anonyymi

        Minä olen ollut sitä jo 18 vuotta.


      • Anonyymi
        Anonyymi kirjoitti:

        Minä olen ollut sitä jo 18 vuotta.

        Niin, mutta, minä olen paras.


      • Anonyymi

        Eli siis stringit pois, ja häshimään!
        #hashset


      • Anonyymi
        Anonyymi kirjoitti:

        Eli siis stringit pois, ja häshimään!
        #hashset

        Thä häh, luulin sitä kirjoitusvirheeksi, perun puheeni, en ole paras, enkä käytä noita ollenkaan.


    • Anonyymi

      Onko Delphissä valmiina joukko-tietorakennetta? Tee siitä listasta, josta kysytään onko stringi siellä, joukko. Tällöin stringin joukkoon kuuluvuus -testaus on vakioaikaista.

      • Anonyymi

        "Onko Delphissä valmiina joukko-tietorakennetta"

        Kyllä on. ks. avainsana (Reserved Word): Set.

        "Tee siitä listasta, josta kysytään onko stringi siellä, joukko."

        Delphissä tuo ei onnistu.
        Joukko on joukko asioita, joista kukin mahtuu joko tyyppiin BYTE tai muuhun sellaiseen tyyppiin, että SizeOf(tyyppi) = 1.

        BYTEn lisäksi sallittuja ovat vakiotyypeistä ShortInt, AnsiChar sekä ne käyttäjän määrittelemät tyypit, joissa S SizeOf(tyyppi) = 1.

        Eli vaikka Delphissä on joukot, ne eivät sovellu tapauksiin, joissa joukon alkiot ovat merkkijonoja.

        Poikkeus:

        Jos eivät ole mielivaltaisia merkkijonoja, vaan kukin merkkijono on vakio, ja noita vakiomerkkijonoja on enintään 256 erilaista, silloin voisi määritellä oman luetellun tyypin, ja laittaa sen eri arvot vastaamaan 256 erilaista vakiomerkkijonoa.


    • Anonyymi

      String sisällön muuttaminen hashiksi, md5- tai crc32 ja vertailu sillä

      • Anonyymi

        Mikä vertailu


    • Anonyymi

      Eikös sinne dictionaryyn voi laittaa avaimeksi merkkijonoa? Joku TDictionary<String, X>, missä tuo X saa olla mitä vaan (vaikka Boolean). Sitten käytät tuota dictionariä vaan niinkuin avainten joukkona. Ja tosiaan, kannattaa tehdä kokonaan uusi lista niistä jätettävistä merkkijonoista.

      Disclaimer: en tunne Delphiä ollenkaan, mutta tuon TDictionary:n löysin täältä:

      http://docwiki.embarcadero.com/CodeExamples/Sydney/en/Generics_Collections_TDictionary_(Delphi)

    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Mielessäni vieläkin T

      Harmi että siinä kävi niinkuin kävi, rakastin sinua. Toivotan sulle kaikkea hyvää. Toivottavasti löydät sopivan ja hyvän
      Ikävä
      38
      1620
    2. Nellietä Emmaa ja Amandaa stressaa

      Ukkii minnuu Emmaa ja Amandaa stressaa ihan sikana joten voidaanko me koko kolmikko hypätä ukin kainaloon ja syleilyyn k
      Isovanhempien jutut
      6
      1341
    3. Nähtäiskö ylihuomenna taas siellä missä viimeksikin?

      Otetaan ruokaöljyä, banaaneita ja tuorekurkkuja sinne messiin. Tehdään taas sitä meidän salakivaa.
      Ikävä
      1
      1285
    4. Ei luottoa lakko maahan

      Patria menetti sovitun ksupan.
      Suomen Keskusta
      9
      1279
    5. Pupuhuhdasta löytyi lähes sadan kilon miljoonalasti huumeita

      Pupuhuhdasta löytyi lähes sadan kilon miljoonalasti huumeita – neljä Jyväskylän Outlaws MC:n jäsentä vangittu: "Määrät p
      Jyväskylä
      42
      1267
    6. Persut petti kannattajansa, totaalisesti !

      Peraujen fundamentalisteille, vaihtkaa saittia. Muille, näin sen näimme. On helppo luvata kehareille, eikä ne ymmärrä,
      Maailman menoa
      4
      1253
    7. Sinäkö se olit...

      Vai olitko? Jostain kumman syystä katse venyi.. Ajelin sitten miten sattuu ja sanoin ääneen siinä se nyt meni😅😅... Lis
      Ikävä
      0
      1234
    8. Housuvaippojen käyttö Suomi vs Ulkomaat

      Suomessa housuvaippoja aletaan käyttämään vauvoilla heti, kun ne alkavat ryömiä. Tuntuu, että ulkomailla housuvaippoihin
      Vaipat
      1
      1210
    9. Hyvää yötä ja kauniita unia!

      Täytyy alkaa taas nukkumaan, että jaksaa taas tämän päivän haasteet. Aikainen tipu madon löytää, vai miten se ärsyttävä
      Tunteet
      2
      1170
    10. Lepakot ja lepakkopönttö

      Ajattelin tehdä lepakkopöntön. Tietääkö joku ovatko lepakot talvella lepakkopöntössä ´vai jossain muualla nukkumassa ta
      1
      1146
    Aihe