Boost Histogram sehr langsam - was mache ich falsch?



  • @hustbaer sagte in Boost Histogram sehr langsam - was mache ich falsch?:

    Wenn du oft fill aufrufst, dann zahlst du bei Boost.Histogram mit dem "Default Storage" auf jeden Fall auch oft für die Fallunterscheidung welcher Storage aktuell gerade verwendet wird (1 Byte pro Zelle, 2 Bytes etc.).

    Machst du halt auto hist = make_histogram_with(std::vector<double>(), axis);

    Und egal wie oft man fill aufruft zahlt man mit "Default Storage" für den Overflow-Check.

    In ROOT war (ist?) lange der Default ein TH1F (1d Hist mit Float_t), wenn man im TBrowser doppelklickt. Irgendwann habe ich mich gewundert, warum die Daten an einer Stelle so glatt aussehen. Stellte sich heraus, dass es an float lag, den f += 1 ergibt eher als man denkt wieder f / (Hist.Precision.1D: double in der .rootrc ist die Abhilfe, falls hier jemand ROOT nutzt). Daher: Overflow-Checks sind schon nett 🙂

    Außerdem tracken Histogramm-Klassen normalerweise noch die Over- und Underflows und auch die quadratischen Gewichtssummen pro Bin (Sumw2 in ROOT), um später Unsicherheiten bestimmen zu können. Gut, ist ggf. hier unnötig.

    In Summe beides vermutlich immer noch nicht viel das stimmt schon.

    Mein ursprünglicher Punkt war einfach: Wenn ein mächtiges Teil wie Boost.Histogram schlechte Performance liefert, man aber bloss einen vector<int> + ein paar Zeilen eigenen Code braucht, wieso dann lange auf die Suche gehen was das Problem mit Boost.Histogram ist? Da schreib ich persönlich lieber die paar Zeilen eigenen Code.

    Wenn eine 3rd-Pary Library aus Boost behauptet, sehr schnell zu sein und das auch im Vergleich zu anderen Libraries einhält, gehe ich nicht als erstes davon aus, dass diese mein Geschwindigkeitshauptproblem ist. Zumal du dir bei einer eigenen Lösung ja auch Gedanken um Daten im Under- und Overflowbin machen solltest... Häufig muss du dann noch hier oder dort einen Spezialfall einbauen etc.



  • @titan99_ sagte in Boost Histogram sehr langsam - was mache ich falsch?:

    Die Daten werden nicht im Render-Loop erzeugt, aber die Achse wird durch Verschieben oder durch Änderungen der Achsengrenzen im Render-Loop neu berechnet. Und soweit ich es bisher verstehe, muss die Achse vor dem Fill definiert werden.

    Jein (also technisch schon)! Mach einfach ein sehr feines Binning und mach dann innerhalb der Loop einfach ein Rebinning je nach Anforderung!


  • Gesperrt

    @hustbaer sagte in Boost Histogram sehr langsam - was mache ich falsch?:

    vec[bin]++ und total++.

    Prefer ++i to i++

    Also ++vec[bin] und ++total, finde ich auch angenehmer zum lesen.

    Edit: Quick C++ Benchmark, ich weiss nicht mehr was stimmt.



  • @titan99_
    Wenn du erstmal die 100.000 Pixel auf eine Textur gezeichnet hast, dann kannst du die danach beliebig zoomen und verschieben, das kostet nichts mehr zur Laufzeit. Und nachdem sich die Eingabewerte ändern (was sehr langsam passiert, weil jemand muss da was eingeben), setzt du ein Dirty Flag und aktualisierst bei nächstes Gelegenheit. Da braucht man immer noch keine 240fps, niemand gibt so schnell was ein.



  • @titan99_ Mir ist die x++ vs. ++x Geschichte bekannt, danke. Ich denke auch dass ich sie besser verstehe als du, denn mich wundert das Ergebnis deines Benchmarks gar nicht.
    x++ vs. ++x ist völlig uninteressant bei eingebauten Typen, speziell wenn man den Wert des Ausdrucks nicht verwendet.

    Bei sowas wie BigInt Klassen ist es dagegen gar nicht egal - selbst wenn man den Wert des Ausdrucks nicht verwendet. Bei manchen Iteratoren ebenso, wobei hier auch viel übertrieben wird. Wenn man "checked iterators" hat ist i++ merklich teurer, ja. Ansonsten mit den meisten Iterator-Klassen eher nicht.



  • @wob sagte in Boost Histogram sehr langsam - was mache ich falsch?:

    Wenn eine 3rd-Pary Library aus Boost behauptet, sehr schnell zu sein und das auch im Vergleich zu anderen Libraries einhält, gehe ich nicht als erstes davon aus, dass diese mein Geschwindigkeitshauptproblem ist.

    Es kommt auch immer drauf an was man braucht/erreichen will. Wenn ich bloss ein einfaches 1D Histrogramm brauche wo alle Gewichte gleich sind etc., dann nehm ich einen vector<int> bevor ich mich mit Libraries rumschlage. Ganz egal was jetzt das Problem ist - also ob die Library langsam ist oder ich sie nur falsch verwende. Zeit geht auf jeden Fall dabei drauf.

    Aber ihr dürft das alle machen wie ihr wollt.



  • @hustbaer sagte in Boost Histogram sehr langsam - was mache ich falsch?:

    Aber ihr dürft das alle machen wie ihr wollt.

    Natürlich. Vielleicht bin ich auch geschädigt, weil ich jahrelang Histogramme gefüllt, gemalt, skaliert, gefittet etc. habe. Da ist mir nie in den Sinn gekommen, statt TH1D einen std::vector<double> zu nehmen. Aber klar, hängt sicher erheblich vom Problem ab. Ich habe in der Zeit auch tatsächlich nie ein Histogramm mit int-Bins benutzt. Ich habe sicher viel mehr 1d-Histogramm-Objekte erzeugt als std::vector-Objekte (sogar möglicherweise std::vector<TH1*> - viele Histos, 1 vector). Und irgendwann überlegt man auch gar nicht mehr, ob ein anderer Datentyp als der bekannte Histogramm-Typ überhaupt in Frage kommt.

    dann nehm ich einen vector<int> bevor ich mich mit Libraries rumschlage

    Daher war es für mich bei dem Begriff "Histogramm" andersrum klar: Standard-Histogramm-Datentyp nehmen, bevor ich mich mit std::vector rumschlage und überlegen muss.



  • @wob
    Ja, klar, wenn ich schon eine gute Library kenne, weiss wie die tut/wie ich sie verwenden muss und ich sie auch schon eingebunden habe (Lizenz gecheckt, Build eingerichtet etc.)... dann nehm ich vermutlich auch die fertige Library 🙂



  • Whatever floats your boat I guess.



  • Or whatever doubles your boat 🙂


  • Gesperrt

    or whatever sinks your boat.

    @hustbaer sagte in Boost Histogram sehr langsam - was mache ich falsch?:

    (Lizenz gecheckt, Build eingerichtet etc.)

    Screenshot
    source


Anmelden zum Antworten