Fórum pro uživatele kancelářského balíku OpenOffice | LibreOffice
 

#1 13. 11. 2009 19:12:13

BartonM
Člen
Registrace: 13. 11. 2009
Příspěvků: 4

Příliš pomalé makro - prosím pomozte

Zdravím,
mám menší problém.
Mám porovnat asi 6000 řad čísel o 20 hodnotách (20sloupců) stylem každá s každou a vypsat počet shod vyšších než 10. Napsal jsem makro (je to součást něčeho většího), funguje, ale trvá to v řádu desítek minut neboi spíš hodin

Přitom to jsou jednoduché cylky... mohli byste mi pls poradit, jak to zrychlit?
Děkuju moc.

Tady je kód:

Sub list2020 (list as Object, lastC as Integer, lastR as Integer)
dim bunka
rem pocet shod 20/20
dim cislaA(19)
dim cislaB(19)
dim p as Integer
for a=1 to lastR 'pro prvni radek az posledni
    for i=23 to 33
        bunka=list.getCellByPosition(i,a)
        bunka.value=0 ' vymaze pocet shod (pro opakovane spusteni)
    next i        
    'print "vynulovano"    
      for b=1 to 20 ' nacte cely radek do cislaA
           bunka=list.getCellByPosition(b,a)
           cislaA(b-1)=bunka.Value
      next b 
      for c=1 to lastR ' pro prvni radek az posledni
          if c<>a then ' ...krome sebe sameho
               for d=1 to 20 ' nacte cely radek do cislaB
                bunka=list.getCellByPosition(d,c)
                cislaB(d-1)=bunka.Value
               next d          
               rem pocet shod
               p=0
               for x=0 to 19
                   for y=0 to 19
                       if cislaA(x)=cislaB(y) then
                           p=p+1
                       end if
                   next y
               next x          
               rem konec
               rem vypise pocet shod
               p=p-10 ' uvazujeme pouze shodu vetsi nebo rovnu 10
               if p >=0 then
                   bunka=list.getCellByPosition(p+23,a) ' vychozi sloupec + p
                   bunka.value=bunka.value+1 ' inkrementuje "1"                  
               end if              
               rem konec          
           end if       
       next c
next a
rem konec
End Sub

Editoval BartonM (13. 11. 2009 21:09:59)

Offline

#2 14. 11. 2009 02:51:31

lp.
Člen
Registrace: 24. 9. 2009
Příspěvků: 844

Re: Příliš pomalé makro - prosím pomozte

Začněte jednoduchou analýzou činnosti makra. Tato makro dělá 6000 * 5999 * 20 * 20 = cca 14,5 mld. porovnání hodnot. Přidejte si režii na načítání, ... To chvíli trvá.

Při průchodu jednotlivými řádky nemá smysl se vracet před aktuální řádek. Pokud se třeba řádek 1 shodoval s řádkem 2, tak se jistě bude shodovat řádek 2 s řádkem 1. Tedy

for c=a+1 to lastR ' a+1 radek az posledni

Napočtené shody budou poloviční, ale to by neměl být problém.

Nefektivní jsou i vnitřní dva cykly (400 porovnání). Pokud by byly pole cislaA a cislaB setříděné, bylo hledání shody mnohem efektivnější, mohlo by stačit průměrně cca 30 porovnání.
Asi bych si řádky setřídil v prvním průchodu, buď na stejném místě nebo na jiném, to zrychlení za to stojí. Tím máme cca 0,5 mld porovnání a polovinu čtení buněk.

Potom je tu otázka stylu programování - příliš mnoho operací s jednotlivými buňkami, neustálé načítání a zapisování. Určitě se vyplatí jedna operace nad celým blokem buněk, než řešit každou buňku zvlášť (nulování buněk na začátku lze nahradit vymazáním celé oblasti, načítání jednotlivých buněk načtením celého řádku, ukládání výsledků do pole a zápis teprve po  zpracování řádku -> úvodní mazání je zbytečné,...).

Asi nejefektivnější bude načtení celého rozsahu 6000x20 buněk do pole, setřídění řádků a provedení všech testů v načteném poli, ukládání výsledků do druhého pole a po ukončení  zápis výsledků do listu.

Offline

#3 14. 11. 2009 15:49:41

BartonM
Člen
Registrace: 13. 11. 2009
Příspěvků: 4

Re: Příliš pomalé makro - prosím pomozte

Moc děkuju,
tak jsem zkusil vaše rady...

ta první (nevracení se před aktuální řádek) pomohla dost výrazně
také mám už předem setříděné hodnoty, takže jsem použil i to druhé zjednodušení a opět se program mnohem urychil...

ale nevím si rady s tím polem. Nikdy jsem s ním nepracoval (jsem teprve začátečník), z knížky jsem vůbec nic nepochopil a vlastně tam toho ani moc nebylo...
...poraďte mi prosím ještě, jak deklarovat toto pole, jak buňky uložit do pole (a opačně), jak pracovat s hodnotamy (popř. i celými řádky)

Moc děkuju
PS: hledal jsem nejdříve i tady na fóru, ale o práci s poly jsem tu nic nenašel...

//Edit: přišlo mi vhodné založit pro tento dotaz samostatné téma

Editoval BartonM (14. 11. 2009 19:19:29)

Offline

Zápatí