Forum: PC-Programmierung std::tuple Implementierungen gesucht


von Vincent H. (vinci)


Lesenswert?

Grüß euch

Ich bin auf der Suche nach einem Drop-In Replacement für std::tuple. Die 
Compilezeiten mit der Implementierung von libstdc++ sind leider 
unerträglich geworden.

Leider lässt mich Google aktuell etwas im Stich, hat da wer was feines 
für mich? Schön wär was ohne zig Abhängigkeiten irgendwohin... und 
möglichst ohne X-facher Rekursion und Vererbung.

tia

von Wilhelm M. (wimalopaan)


Lesenswert?

Vincent H. schrieb:
> Grüß euch
>
> Ich bin auf der Suche nach einem Drop-In Replacement für std::tuple. Die
> Compilezeiten mit der Implementierung von libstdc++ sind leider
> unerträglich geworden.

Ups, was machst Du denn mit dem armen std::tuple<>?

> Leider lässt mich Google aktuell etwas im Stich, hat da wer was feines
> für mich? Schön wär was ohne zig Abhängigkeiten irgendwohin... und
> möglichst ohne X-facher Rekursion und Vererbung.

Ich habe nur meine abgespeckte, naive Variante für µC, die aber 
(natürlich) auch wieder eine N-fache Vererbungstiefe hat.

von Vincent H. (vinci)


Lesenswert?

Wilhelm M. schrieb:
> Vincent H. schrieb:
>> Grüß euch
>>
>> Ich bin auf der Suche nach einem Drop-In Replacement für std::tuple. Die
>> Compilezeiten mit der Implementierung von libstdc++ sind leider
>> unerträglich geworden.
>
> Ups, was machst Du denn mit dem armen std::tuple<>?

https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAKxAEZSAbAQwDtRkBSAJgCFufSAZ1QBXYskwgA5NwDMeFsgYisAag6yAwgREAHBpg3YOABgCCpswoKqAtkwUQAlOoDsfc5dWqmIoqpsNABFVQQJ0EBAdfUN3L28E%2BgTVLlJk2TSEgBZM7wBWXNUANkLXQoAOQoBOQtoTXNok71pU%2BOTaDMScxILEksSyxMrEmoSuerGmlNSxzu8uHLax3vn%2B%2BcH54fnR71kJ3anZGd251Vlu3ZWzkqXdjbOts53VLP2Xqazjl9Osi5errJrF73LKVW4vZ55N55KZ5L55U55P55K55IF5e55R55Z5FergopTIpfIqnIp/IpXIpAor3IqPIrPVxvVxTVytczJbyuU6uP6uK6uIGue6uR6uZ7lN7lKblL7lU7lRacrnlK7lIHle7lR7lZ5VN5VKZVL5VU5VP5VK5VG4q5JVe5VR5VZ51fZ1Jp1Y51OZ1C51FZ1NZ1DZ1MF2xImHaNd2NTKNb0deO0f20QO0YO0UO0LaNaPjUjglqerjeri%2BhbxriBrjBrihri5rjRvbx2Seo6FiPNWS%2B85twOyYOyUOyXOyaOveNZT2fae%2B35dsxc1QpwOA6eh0HT6NQ%2BMw/fehH7/0o/e25dctOhrH76N4%2BOEx/e0mP/2Ux/B2mP8OX9qM%2BNmUAz12UA30%2BUAwMhUA0MxUA6MpSXFcc09OV4wVdD/TVdDgy1dDcz1eMDSIz0TSQq8zSI/0rSI4MHSI3MXUycZ9nGJpxmOcY5nGZU/zGEwVnGNZxg2cYtnGHYuDqZi43mFoZO4lMZMEjNyOSKTRJzGTJILeYpOY0sDO4ys9ME2sDNExs1LGZtmNbeZ2zszjezsi5y0Eoc7NEsc7MkqdwQWdi53mLJuMXELBI3ELRO3ELJL3eYD0Sjk%2BMS7ikWYs9EuEjFMvEnFmIfVZ2OJQruPJazVkE6lCtE%2BlCskoD1nY0D1m4iD1kE6CApFZi4PWSTEM2di0M2bilWY7DNmEvDNl/FdG0k4jtnYsjtm4i1mJo7ZhPo7ZxKY3YTHxbszhMJo9mOPY5j2C49hWPY1j2DY9i2PYdnbfZ2wu%2BTwXbG6lIOB7VIOF6tIOD7dLOfTdkM2GbsrP7q0yI4nvrFGrNhj77LORyTiulyTju2QHs8v6RxRnyTg%2BqddhnFHgrOUKGburIHqipmXu3P6sg%2BhKziSgWruPS47qygWntyy43oK3YHz%2Bp85au185buj85ae785begC7i%2B1kUdAv6eUNu6BUNp7eruN6JRRoaHgu0aHhuia/qmh4ntmh43sI3ZlqeC61qeG7Nr9h6bUqp4XqdFHDpeY7MleJpXmOV45leC5XhWV41leDZXnmrlXh2Gd9hnZP5O8Gd08B95s5B958/B94S4LcFPmTuGXnLROTO77PzKr9Gh62T4S5x0Lk87dvCe%2BTOScTzyq4p5fR4nRPaZeemq8Z3508Xdu2Y33Osnz2Kt5L/m2eTuFE5F/5M/FtmLxXNn89vKvZZeIrv%2BT0qq5Vt/TO6tv65y1t/QuyRAQlyasCZOrVgTpw6sCbO0Eq5W2BKPW2VdELtxlInJ2oJ04TRwdnDUBD846gISXf2vNk5kXbpRKuocITZwjsw/OMdmE7ChPsKETQoTHChHMKEvEVxQhWFCNYUINhQi2FCHh0l8iyVUDCIRSZlEXBhJI1S4IYSyObjCHhUM4QCK7nCERfc4SSMHqo4edjIEJDhDwnGCIBGdnyLPBEWiF6eOkSvVRVNAk8P8qdJEAjGZIhEeFVRR98gcyRLI8%2BSIeH8xRAI2%2Bej74oi0eLFE0ipaqI/kUnhP80QCP/qowBaIxFcjRJImq%2BRwFonkbrVRsCMQCIQRiERyCMSSO6mEjBGJ5HYNUfbLEAinZYhESQ8ZkjyH5C9liRxSyeH%2BxxAIoOOIREsJxJI9hqi9pHPkXHPEJ1UrFHOpkPExw8RzDxBcPEKw8RrDxBsPEWw8Q7EJPsQkTRCQpRXISB5tdCQvIboSD5zdCQ/KhsSAFXdiQPMRqdYkLzbHEg%2BZjYotlvCkj%2BXjYoHjiUPP7Pi3xxKX5clJB8oJpIfmb3JACxm5IHkxPJC8jm5IPnczRbzG5/NKQAtvvi%2B%2BlInni0pG8wplIvlf2pBc4FitiiVOpA8iq%2BKQHUjeeA6kXy2m0j%2BQbfFRs0Um1NU882pq3kYNpF8sZ9I/n4PxU7ekDzXZovdvSN5Xt6RfN9sUf2jIAVB0ZA8lhjIXkRwJMcxkXy47Mn2MyJozJjjMjmMyC4zIVjMjWMyDYzJVmqGZDsVkyaVGsnTRokttdWS5obqyQtzdWRlrbqddkqau7skzX3dkubbHskLTi9kZacY8lTdPDts8eTZspTyfNASeRbB5GWzefJU2Mz5Jmg%2BHa4klo5nyQt58%2BRlv5gKVNoqS33wFNm8WApqXJAFIW4pAoy0/yFKmypQpM2apLSAoU%2BbwFCmLUKMtsCRSpoQSKTNyCRS5rQSWjBIoV1jLFEqrkYpU1OzFJmuZYpc2LJLV7MUK7A0SmTUaTIEogWYaYSWlhEpc2HIlIWrhDGdhSn2FKJoUpjhSjmFKWpyQpQrClGsKUGwpRbClJxpRqgZS8crgpmtMoLgyjE7o06MopPNxlJxqGcpeNdzlIJvucoxO2LlFJqy4I5ScZxgqXjJKFSCfJQpylCoJMBIVDJ9e3glQYZE9vBTjMlSCZiUqMTHMlRSfPkqTj/M1S8cydp%2B%2Bap1PizVBJwpaoZNfw1NxlVGp%2BOAI1MJhIGoxONIU%2BAjUMm2lam4yahTCCtSCeQVqMTgzLlaik/1VrnH7Y6l407HUgm5k6jE0RnUUmqF2cDXqbjVGAtBz1IJlheoxOHL1FJ9jeodgGiCwkA0TQDTHANHMA0FwDQrANGsA0GwDRbANId%2BTRozu/VOkaK7tcjR3YbkaJ7zcjSHahiaM7XcTRXdRZck0d3bEmiezik0h2cZmjOySs0V33Nmju2Tb7ASzQvf86oC0%2BwLRncZhaK7MSLR3Y5haJ7fK4cCu8FaCngsrQXfvlaG74srQPcKVaF7X8bTHfZyqm0F3AE2huyAm0D3wE2he20h0FOWsOlo/aC1ZPkEOju4hh0T2BsOkO/bJ0Z2nZOiu56uH7snQPa9k6F7gaXQU5W2ToOLorssJdHdmN33jkuhe3HN0Ew3RJDdDMN0nQ3TdDdL0N0/Q3SDDdMWt0owPQR/OlH86Mfzpx/Ogn86Sfzop/Omn86wwPRZ5MO2y5Xo89wy9LIDgrgggaA8BYTwHepBOEYNIPIUhSAsGkCYEfqBpCaH4PwUIohxCYHUOWWgI%2BCDj/7wPgA1iAPEAA6BUKIowdF8y0ASg%2BpBZBH2PqQE/SBT6kCPwQIB6jr9v/30gcBYAwEQCgVAthdA8ADAyAKAIA0AACgDMBiAQBgATYAAzIAggKA5/CAAAIw31IFQIUCYGIAAE9pBV9SBwDbBMAWACAAB5FgBgfA9/UgLAewNgAwDA/AYgTAZAAgPAAAN0wGf1oMwAAA82C/BJApBCDrBMAGAMCCBiA8BbAN8B9mA2AUBZ9eBGA8BUDn9YAWAmASCQBUDUBUAwhSBuDoDRDqRN979dAODUAWBeCABaMIdAYITgXgfgLMVQOwuApAgA5gJAuwrAKwhAYISkBEIoJ/BfCQOgBQofa/DAh/fgjUOw8kVQYAZAZAEtPfWQVQCAXAQgEgZfPGTQf/QA4Ago2gFwGfVw3gNfeQ7fEAU%2BPfHtT4IhNUEwXmSoSQy/EfOQvcG/O/B/J/F/UgN/CfAfL/X/UQAgXQPwcgSgcAkoqAugUgTAfAIgaA%2BgAAd2ICYF0AII/06OH1HziOkDkFoFUA2MIAQFUASKKCSKyBSLSIyNkBqPfycAHwQEwCYCwGgOcAvyv1IB6PqD6Mn2kEGNf1qNIB3wnD3wzF%2BGe0JEJC1Bok6OeKONoIGOGIhM6K4FiPRNBMxNeIHxMMEDwBsPqKAA

(sry URL shortener wollt grad nicht)


Das Beispiel compiliert mit libstdc++ quasi gar nicht mehr, außer man 
hat ein kleines Rechenzentrum daheim. Verwendet man statt libstdc++ nun 
etwa libc++, dann is das ganze selbst auf meiner Krücke daheim binnen 
20s gegessen. Von anderen Implementierungen brauch ich gar nicht erst 
anfangen... selbst eine hana::tuple, die sich Performance-technisch 
meines Wissens nach eher im Mittelfeld der Meta-Libs findet bricht das 
auf 10s runter.

Die libstdc++ Implementierung ist zumindest für größere Dinge der 
absolute Horror.

von Wilhelm M. (wimalopaan)


Lesenswert?

Wie so oft, ist dass was Du da zeigst, sicher nicht Teil Deines 
Problems, denn dafür brauchst ja keinen heterogenen Container wie 
std::tuple<>, ein std::array<> oder std::integer_sequence<> hätte es 
auch getan.

von Vincent H. (vinci)


Lesenswert?

Wilhelm M. schrieb:
> Wie so oft, ist dass was Du da zeigst, sicher nicht Teil Deines
> Problems, denn dafür brauchst ja keinen heterogenen Container wie
> std::tuple<>, ein std::array<> oder std::integer_sequence<> hätte es
> auch getan.

Ernsthaft, Willhelm!
Du glaubst doch nicht dass ich da nur Integer reinstopfen will... :D

von Wilhelm M. (wimalopaan)


Lesenswert?

Sag ich doch, aber was soll denn das Beispiel?

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Wilhelm M. schrieb:
> Sag ich doch, aber was soll denn das Beispiel?

Zeigen, dass Tuple recht schnell langsam wird. Ich finde das recht 
erstaunlich.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Vincent H. schrieb:
> selbst eine hana::tuple, die sich Performance-technisch
> meines Wissens nach eher im Mittelfeld der Meta-Libs findet bricht das
> auf 10s runter.

Dann nimm das doch?

von Vincent H. (vinci)


Lesenswert?

Wilhelm M. schrieb:
> Sag ich doch, aber was soll denn das Beispiel?

Das Beispiel zeigt mein Problem in seiner destillierstes Form. Ob du da 
jetzt Integer, Strings oder Bratwürsteln rein wirfst ändert nicht das 
Geringste daran, dass sich mit der libstc++ keine Tupln dieser Größe 
anlegen lassen.

/edit
Die hana::tuple ist aktuell nicht mit meinen Algorithmen konform, die 
auf std::tuple arbeiten. Das ganze wäre zwar mit ein wenig Aufwand 
machbar, ich würde aber eben wie gesagt ein "Drop-In" Replacement 
bevorzugen.

: Bearbeitet durch User
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Probiere doch mal https://github.com/kvasir-io/mpl aus. Der Odim Holms 
legt sehr viel Wert auf Performance (http://metaben.ch).

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Hier mein Versuch:
https://github.com/Erlkoenig90/MetaUtils/blob/master/tuple.cc

Ohne das printTuple (hast du in deinem Beispiel ja auch nicht) ca 5 
Sekunden. Mit printTuple ca 1 Minute. Kommt ganz ohne 
Rekursion/Iteration aus, aber nur eine rudimentäre Implementation ohne 
viele Features. Das API ließe sich an std::tuple anpassen.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Hier ist die nicht-rekursive Implementierung, die so wie Niklas' mit 
Mehrfachvererbung arbeitet:

http://mitchnull.blogspot.de/2012/06/c11-tuple-implementation-details-part-1.html

von Vincent H. (vinci)


Lesenswert?

Super Danke! Die schau ich mir mal an.

von Wilhelm M. (wimalopaan)


Lesenswert?

Eigentlich sollte die Version mit den Expression-Templates wohl die 
schnellste sein (wie bei HANA). Ich würde bzgl. der Compile-Time 
erwarten: Rekursive Vererb. > Mehrfachvererb. > Expression-Template 
(lambda).

Das Rekursive Vererb. > Expression-Template (lambda) hat Louis Dionne ja 
auf der CppCon2014 gezeigt. Allerdings keinen Vergleich zu 
Mehrfach-Vererb.

Vielleicht magst Du das ja mal ermitteln?

von M.K. B. (mkbit)


Lesenswert?

Nur aus Interesse. Welche Anwendung hast du denn für ein so großes 
Tuple?

von Sheeva P. (sheevaplug)


Lesenswert?

Vincent H. schrieb:
> Ich bin auf der Suche nach einem Drop-In Replacement für std::tuple. Die
> Compilezeiten mit der Implementierung von libstdc++ sind leider
> unerträglich geworden.
>
> Leider lässt mich Google aktuell etwas im Stich, hat da wer was feines
> für mich? Schön wär was ohne zig Abhängigkeiten irgendwohin... und
> möglichst ohne X-facher Rekursion und Vererbung.

Eine performantere Implementierung von std::tuple kenne ich leider 
nicht.

Aber als ich Deine Compilereinstellung von "-ftemplate-depth=65535" sah, 
mußte ich an eine Stelle aus "Using the GNU Compiler Collection (GCC)" 
denken:
1
-ftemplate-depth=n
2
3
    Set the maximum instantiation depth for template classes to n.
4
    A limit on the template instantiation depth is needed to detect
5
    endless recursions during template class instantiation. ANSI/ISO 
6
    C++ conforming programs must not rely on a maximum depth greater 
7
    than 17 (changed to 1024 in C++11). The default value is 900, as
8
    the compiler can run out of stack space before hitting 1024 in 
9
    some situations.

Was machst Du da? Einen Pentest, um die Grenzen des GCC auszutesten? ;-)

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Dass -ftemplate-depth > 1024 den Stack umbringt dürfte eine veraltete 
Doku sein. Im Netz finden sich teilweise Beispiele die mit > 3200 noch 
compilieren.

Was ich damit mache wird unter anderem hier von Willhelm erklärt:
Beitrag "Re: constexpr Argument-Wrapper"

von Wilhelm M. (wimalopaan)


Lesenswert?

Vincent H. schrieb:
> Dass -ftemplate-depth > 1024 den Stack umbringt dürfte eine veraltete
> Doku sein. Im Netz finden sich teilweise Beispiele die mit > 3200 noch
> compilieren.

Das denke ich auch, bei mir gehört mittlerweile -ftemplate-depth=2048 zu 
den "normalen" Flags.

von Niklas Gürtler (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Das denke ich auch, bei mir gehört mittlerweile -ftemplate-depth=2048 zu
> den "normalen" Flags.

Ich mache auch eine Menge Metaprogrammierung und hab diese Option noch 
nie benutzt. Viel kann man durch schlaue Nutzung von Parameter Packs 
erschlagen, siehe mein Beispiel von oben.

von Sheeva P. (sheevaplug)


Lesenswert?

Vincent H. schrieb:
> Dass -ftemplate-depth > 1024 den Stack umbringt dürfte eine veraltete
> Doku sein. Im Netz finden sich teilweise Beispiele die mit > 3200 noch
> compilieren.

Das mag sein, aber selbst 3200 ist ja noch ziemlich weit -- ein Faktor 
von über zwanzig! -- von den 65535 entfernt, die Du verwendest. Mit 1024 
gibts jedenfalls keinen Timeout mehr, sondern einen Compilerfehler.

Insofern bleibe ich bei meiner Auffassung, daß das wesentliche Problem 
nicht std::tuple ist, sondern diese Compilereinstellung.

von Vincent H. (vinci)


Lesenswert?

Sheeva P. schrieb:
> Vincent H. schrieb:
>> Dass -ftemplate-depth > 1024 den Stack umbringt dürfte eine veraltete
>> Doku sein. Im Netz finden sich teilweise Beispiele die mit > 3200 noch
>> compilieren.
>
> Das mag sein, aber selbst 3200 ist ja noch ziemlich weit -- ein Faktor
> von über zwanzig! -- von den 65535 entfernt, die Du verwendest. Mit 1024
> gibts jedenfalls keinen Timeout mehr, sondern einen Compilerfehler.
>
> Insofern bleibe ich bei meiner Auffassung, daß das wesentliche Problem
> nicht std::tuple ist, sondern diese Compilereinstellung.


Nein das Problem ist std::tuple, und zwar explizit die libstdc++ 
Implementierung. Die libc++ Implementierung is zwar auch nicht perfekt, 
compiliert aber zumindest noch locker bei ~1000 Objekten.

Wenn du mir nicht glaubst probiers halt aus...


/edit
-ftemplate-depth "pre-allokiert" übrigens nichts. Selbst wenn ich da 
200.000 oder so einstell compiliert das Programm durch, solang der 
Speicher aussreicht.

: Bearbeitet durch User
von Vincent H. (vinci)


Angehängte Dateien:

Lesenswert?

Im Anhang eine Grafik aus der boost::hana Doku, wo verschiedene Tuple 
Implementierungen via metabench (ebenfalls von Louis Dionne) verglichen 
werden. Interpolier die std::tuple Kurve mal vor deinem geistigen Auge 
linear...

von Wilhelm M. (wimalopaan)


Lesenswert?

Ah, sehr cool.

Genau das hatte ich gesucht ... und stützt meine Vermutung.

Und was hindert Dich daran, die HANA-Version zu nehmen?

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Gar nichts, aber ich experimentier heut noch ein wenig. ;)

Die Version hier ist nach meinen ersten Tests noch flotter:
https://github.com/taocpp/tuple

~8s für eine Tuple mit 2048 Einträgen!

von Vincent H. (vinci)


Lesenswert?

Ich glaub das wird noch ein paar Leute interessieren, zumindest die 
üblichen Verdächtigen. ;)

Hat schon einmal wer von euch ausprobiert mit einem "for_each" über 
große Tupeln zu "iterieren"? Und mit iterieren mein ich hier 
funktionelles Iterieren, also quasi für jeden Typen innerhalb der Tupel 
eine Funktion aufrufen.

Via C++17 ganz klassisch etwa so ~
1
template<typename T, typename F, size_t... Is>
2
constexpr void for_each_impl(T&& t, F&& f, std::integer_sequence<size_t, Is...>) {
3
  (f(std::get<Is>(std::forward<T>(t))), ...);
4
}
5
6
template<typename T, typename F>
7
constexpr void for_each(T&& t, F&& f) {
8
  // for_each_impl( perfect forwarding.. blabla )
9
}
10
11
int main() {
12
 
13
  // Tupel hier usw.
14
15
  for_each(t, [](auto&&){});
16
}

Bei dem Versuch über eine 1024 Elemente Tupel zu iterieren schießt der 
GCC (7.3.1) erfolgreich einen PC mit 32GB RAM ab. Welche Flags man da 
setzt ist nach meinen Versuchen recht egal, scheinbar fordert das 
Instanzieren der ganzen Funktionsaufrufe immer mehr und mehr Speicher 
an, auch dann wenn ein Großteil davon später wieder entsorgt wird... 
(weil zum Beispiel leer)

Clang 6.0.0 braucht für das selbe Beispiel bei mir ~2.5GB RAM und 31s. 
Ich bin jetzt natürlich kein Experte was Compiler angeht, aber wenn die 
aktuelle Entwicklung von C++ weiterhin so funktional angehaucht bleibt 
und wir bald etwa Reflection und dergleichen bekommen, dann seh ich 
ehrlich gesagt keine sehr rosige Zukunft für den guten alten GCC...


/edit
Sry für Tipfehler und Co, schon zu spät für mich.

: Bearbeitet durch User
von tictactoe (Gast)


Lesenswert?

Vincent H. schrieb:
> Bei dem Versuch über eine 1024 Elemente Tupel zu iterieren schießt der
> GCC (7.3.1) erfolgreich einen PC mit 32GB RAM ab.
> ...
> Clang 6.0.0 braucht für das selbe Beispiel bei mir ~2.5GB RAM und 31s.
> Ich bin jetzt natürlich kein Experte was Compiler angeht, aber wenn die
> aktuelle Entwicklung von C++ weiterhin so funktional angehaucht bleibt
> und wir bald etwa Reflection und dergleichen bekommen, dann seh ich
> ehrlich gesagt keine sehr rosige Zukunft für den guten alten GCC...

In diesem speziellen Fall ist der Speicherverbrauch eher der 
tupel-Implementierung geschuldet und nicht der Compiler-Implementierung, 
denke ich: libstdc++ verwendet eine rekursive Struktur, libc++ 
Multiple-Inheritance.

von Vincent H. (vinci)


Lesenswert?

tictactoe schrieb:
> Vincent H. schrieb:
>> Bei dem Versuch über eine 1024 Elemente Tupel zu iterieren schießt der
>> GCC (7.3.1) erfolgreich einen PC mit 32GB RAM ab.
>> ...
>> Clang 6.0.0 braucht für das selbe Beispiel bei mir ~2.5GB RAM und 31s.
>> Ich bin jetzt natürlich kein Experte was Compiler angeht, aber wenn die
>> aktuelle Entwicklung von C++ weiterhin so funktional angehaucht bleibt
>> und wir bald etwa Reflection und dergleichen bekommen, dann seh ich
>> ehrlich gesagt keine sehr rosige Zukunft für den guten alten GCC...
>
> In diesem speziellen Fall ist der Speicherverbrauch eher der
> tupel-Implementierung geschuldet und nicht der Compiler-Implementierung,
> denke ich: libstdc++ verwendet eine rekursive Struktur, libc++
> Multiple-Inheritance.


Ich verwende in beiden Fällen bereits meine eigene "Vererbungs" Tupel.

von Basic Programmierer (Gast)


Lesenswert?

Boooaahhh ... ich muss mich hinsetzen.

Habe von den ganzen Beiträgen kein Wort verstanden.
Und ich dachte ich könnte sogar C programmieren.

Vielleicht kann mir bitte jemand einen Hinweis geben
wo ich mich einlesen (und dann umbringen) kann ....

Vincent H. schrieb:
> std::tuple

??

von Wilhelm M. (wimalopaan)


Lesenswert?

Vincent H. schrieb:

> Hat schon einmal wer von euch ausprobiert mit einem "for_each" über
> große Tupeln zu "iterieren"? Und mit iterieren mein ich hier
> funktionelles Iterieren, also quasi für jeden Typen innerhalb der Tupel
> eine Funktion aufrufen.

Jein, jedenfalls nicht mit Elementanzahlen jenseits von ca. 150. Ich 
hatte ja mal den Anwendungsfall einer Menu-Struktur. Dazu brauchte ich 
ein Laufzeit get(...), was man dann ja etwa so realisiert wir Du es 
gemacht hast: Du hast ein for_each(), ich brauchte auch ein apply(T&& 
tuple, size_t index, F&& function).
Die Compilezeit geht in der Tat exp. in die Höhe, mich hat allerdings 
mehr die Code-Explosion gestört, da ich sehr viele unterschiedliche 
Typen im Tuple hatte.

Wie ist denn das Tupel parametriert? Sind es alles unterschiedliche 
Typen, also etwa integral_constant<...> im Test?

Hast Du mal einen Vergleich zu der dritten Tuple-Variante mit 
expression-templates gemacht (ich denke, Boost-Hana ist so realisiert).

von Vincent H. (vinci)


Lesenswert?

Wilhelm M. schrieb:
> Wie ist denn das Tupel parametriert? Sind es alles unterschiedliche
> Typen, also etwa integral_constant<...> im Test?

Ja, wobei ich hier noch prüfen muss was der Compiler aus "ähnlichen" 
Typen tatsächlich macht. Ich denke grad in so Fällen wo sich Typen 
lediglich um eine Konstante (etwa für eine ID) unterscheiden kann sehr 
gut optimiert werden.


Wilhelm M. schrieb:
> Hast Du mal einen Vergleich zu der dritten Tuple-Variante mit
> expression-templates gemacht (ich denke, Boost-Hana ist so realisiert).

Bei meinen Tests war die Expression Template Variante zwar schneller als 
die mit Mehrfach-Vererbung, dafür war auch der Speicherverbrauch wieder 
höher!


Fürs "drüber iterieren" (for_each, apply, etc.) und das erzeugen von 
Funktionsaufrufen sollte die Tupel-Implementierung ja dann eigentlich 
keine Rolle mehr spielen?

von Niklas Gürtler (Gast)


Lesenswert?

Basic Programmierer schrieb:
> Vielleicht kann mir bitte jemand einen Hinweis geben
> wo ich mich einlesen (und dann umbringen) kann

Metaprogrammierung ist wie ich finde ein sehr spannendes Thema das ganz 
neue Arten zu Programmieren ermöglicht. Allerdings ist es auch 
kompliziert und abstrakt - ziemlich weit von "normalem" C entfernt. 
Zuvor sollte man gute Grundlagen in C++ haben. Hier ein paar 
Einstiegshilfen:

https://de.wikipedia.org/wiki/C%2B%2B-Metaprogrammierung

https://www.amazon.com/C-Templates-Complete-Guide-2nd/dp/0321714121

https://stackoverflow.com/a/388282/4730685

von M.K. B. (mkbit)


Lesenswert?

Basic Programmierer schrieb:
> Habe von den ganzen Beiträgen kein Wort verstanden.
> Und ich dachte ich könnte sogar C programmieren.
>
> Vielleicht kann mir bitte jemand einen Hinweis geben
> wo ich mich einlesen (und dann umbringen) kann ....

An dieser Stelle war ich auch mal. Am Anfang denkt man bei Templates ob 
die Autoren noch ganz dicht sind, aber mittlerweile finde ich das auch 
praktisch. :-D

Aus meiner Erfahrung verlief der Übergang von C zu C++/STL 
(Standardbibliothek) in mehreren Schritten über ~10 Jahre.

1) Verwendung von Funktionen und Objekten aus der Standardbibliothek.
2) Objektorientierung
3) Verständnis der tieferen Konzepte der Sprache
4) einfache Templates selbst schreiben
5) Template Meta Programmierung

Auch für Mikrocontroller ist Template Meta Programmierung vorteilhaft, 
weil z.B. komplizierte Logiken automatisch vom Compiler zur Compilezeit 
ausgerechnet werden können und keine Kosten zur Laufzeit haben. Das 
ganze funktioniert dann auch auf allen standardkonformen Compilern 
sofern man nicht wie hier an die Grenzen gehen muss.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.