Zeit basiertes lesen optimieren



  • Ich möchte x Gruppen von variablen mit verschiedenen sekunden-raten verarbeiten (Berechnungen usw.) damit ich nichts unnötig mehrfach mache berechne (gcd) ich die kleinste rate mit der ich alle gruppen-raten abdecken kann und prüfe dann im Zyklus per modulo wann eine Gruppen Verarbeitung angestoßen wird

    Das sieht dann so aus:

    3 Gruppen (3sek, 4sek, 6sek)
    Ergibt 1sek Zykluszeit

    0: (3,4,6)
    1:
    2:
    3: (3)
    4: (4)
    5:
    6: (3,6)
    7:
    8: (4)
    9: (3)
    10:
    11:
    12: (3,4,6)
    13:
    14:
    ...

    Soweit so einfach

    Jetzt hab ich festgestellt das ich auf die sich bildenden Gruppen optimieren koennte

    D.h. aus den Gruppen 3sek, 4sek und 6sek (koennen auch mehr sein) wuerde ich gerne Die kombinierten Gruppen (3,4,6), (3,6), (3), (4) usw bilden damit ich dann damit ein optimierte Gruppen bauen kann

    Bisher hab ich mal probiert alle vorkommende kombinierte Gruppen aus der aufsteigenden Multiplikation aller Basis raten zu erzeugen, sieht nicht elegant aus und enthält Lücken, viel if/else und denke es sollte nach meinem Gefühl nur ein kurzer algo sein

    Folgendes ist mir klar:
    Es kann bei entsprechender Menge an eingangsgruppen sehr viele kombinierte Gruppen geben - das ist OK

    Kennt jemand einen entsprechenden Algorithmus oder hat tips für mich - falls jemand code hat ist die Sprache egal (ich adaptiert das dann)



  • Ich kann dir nicht ganz folgen, was du vor hast oder du verkomplizierst das ganze zu stark.

    Die geringste Ausführungszeit hast du dir ja bereits berechnet. Da alles nach einem Scheduler klingt würde ich nun jede Variable ein Objekt erstellen, welches sein Ausführungsinterval und den nächsten Ausführungszeitpunkt kennt (Achtung C#).

    class VarItem
    {
        public int Interval { get; set ; }
        public DateTime NextExecution { get; set; }
    
        public virtual void Update()
        {
            // do execution ??
    
            // update next execution time
            this.NextExecution = DateTime.Now.AddSeconds(this.Interval);
        }
    }
    

    In der Methode die nach der geringsten Zykluszeit aufgerufen wird, würde ich dann nur noch alle Einträge durchgehen und die Aktualisierung ausführen.

    private void ExecuteInterval()
    {
        foreach(VarItem item in this.VarItems)
        {
           if(item.NextExecution <= DateTime.Now)
           {
               item.Update();
           }
        }
    }
    

    Natürlich alles an deine Bedürfnisse angepasst, sollte das funktionieren. - Dort nun vorher schon unnötige Optimierung reinzustecken halte ich für Unfug.



  • Stell dir einfach vor das mein lesen für die kombinierte Gruppe (3,4,6) in Sekunde 12 um ein vielfaches schneller ist als (3),(4),(6) nacheinander abzufragen (die abfragen können nicht parallelisiert werden da teilweise über externe Hardware kommuniziert wird die das nicht kann)
    Dein c# Beispiel ist leider unbrauchbar weil ich keinerlei "Strukturprobleme" dieser Art habe sondern nur ein Optimierung Potenzial nutzen will



  • ich habe inzwischen eine, denke ich, funktionierende Lösung gefunden (danke WP)
    Vergleichstest mit der bisheriger Modulo-Zerlegung ohne kombinierte Gruppen zeigen keine Fehler

    habt ihr noch Idee wie ich das noch einfacher (z.B. weniger Filtern) anders machen kann - oder ob mein Algorithmus z.B. Denkfehler enthält

    so funktioniert es:

    Legende:
    Gruppen = [n Variablen] (unique) Pollrate, sortiert
    CGruppen = enthaehlt die vorkommenden Gruppen-Kombinationen
    GCD = Greatest common divisor
    LCM = Least common multiple
    Integer-Faktoren = alle Teiler einer Zahl

    Gruppen
    A 11 sek
    B 20 sek
    C 50 sek

    Alle-Gruppen-Rate-GCD: 1 sek <-- das ist meine Poll-Rate fuer den Thread/Timer

    nun zum Algorithmus: (zur Anschauung nutze ich die Kalkulatoren von http://www.calculatorsoup.com/calculators/math/)

    http://www.calculatorsoup.com/calculators/math/lcm.php von 11,20,50
    Alle-Gruppen-Rate-LCM: 1100

    http://www.calculatorsoup.com/calculators/math/factors.php von 1100
    Integer-Faktoren = {1,2,4,5,10,11,20,22,25,44,50,55,100,110,220,275,550,1100}

    aus Integer-Faktoren CGruppen erzeugen: d.h. welche Gruppen passen in welchen Faktor (d.h. Integer-Faktor ohne Rest durch Gruppen-Rate teilbar)

    z.B. bei Integer-Faktoren[14] = 220 sek
    220 % 11 == 0 -> A drinn
    220 % 20 == 0 -> B drinn
    220 % 50 == 0 -> C nicht drinn

    dann entferne ich die CGrouppen die leer sind oder von einer Vorgänger-Gruppe.Rate durch Modulo ohne Rest teilbar ist und die gleichen Gruppen enthaelt
    CG0(1 sek) = { } <-- keine, weg damit (Optimierung: kleiner als kleinste Gruppen-Rate - daher auch schon nicht drinn)
    CG1(2 sek) = { } <-- keine, weg damit (Optimierung: ^)
    CG2(4 sek) = { } <-- keine, weg damit (Optimierung: ^)
    CG3(5 sek) = { } <-- keine, weg damit (Optimierung: ^)
    CG4(10 sek) = { } <-- keine, weg damit (Optimierung: ^)
    CG5(11 sek) = { A }
    CG6(20 sek) = { B }
    CG7(22 sek) = { A } <-- schon durch CG5 abgedeckt (CG7.rate % CG5.rate == 0 && CG7.groups == CG5.groups)
    CG8(25 sek) = { } <-- keine, weg damit
    CG9(44 sek) = { A } <-- schon durch CG5 abgedeckt
    CG10(50 sek) = { C }
    CG11(55 sek) = { A } <-- schon durch CG5 abgedeckt
    CG12(100 sek) = { B C }
    CG13(110 sek) = { A } <-- schon durch CG5 abgedeckt
    CG14(220 sek) = { A B } <-- Rate wird schon durch CG5 abgedeckt - aber es sind andere Gruppen enthalten - also doch drinn
    CG15(275 sek) = { A } <-- schon durch CG5 abgedeckt
    CG16(550 sek) = { A C }
    CG17(1100 sek) = { A B C }

    gefilterte CGruppen
    CG0(11 sek) = { A }
    CG1(20 sek) = { B }
    CG2(50 sek) = { C }
    CG3(100 sek) = { B C }
    CG4(220 sek) = { A B }
    CG5(550 sek) = { A C }
    CG6(1100 sek) = { A B C }

    jetzt einfach nur einen Thread mit der Poll-Rate Alle-Gruppen-Rate-GCD sekunde laufen lassen und einen Counter mit Alle-Gruppen-Rate-GCD hochzaehlen (beim ueberlauf faengt er ja wieder bei 0 an)
    und von unten nach oben durch die gefilterte Liste gehen und bei einem Treffer die entsprechende CGroup nutzen (und die auch schon funktionierende "Optimierung" die dahinter steht)

    ...
    196:
    197:
    198: CG0 = { A }
    199:
    200: CG3 = { B C }
    201:
    202:
    203:
    204:
    205:
    206:
    207:
    208:
    209: CG0 = { A }
    210:
    211:
    212:
    213:
    214:
    215:
    216:
    217:
    218:
    219:
    220: CG4 = { A B }
    221:
    222:
    ...


  • Banned

    This post is deleted!

Log in to reply