Fragen: JAVA (Geschwindigkeit), D()



  • Dravere schrieb:

    Der "Small Object Allocator" nutzt einfach die Sprachmöglichkeiten für die eigene Speicherverwaltung. Das ist kein Hack, das ist kein hinbiegen, das ist nur ein Nutzen von Features.

    Workaround bedeutet auch nicht Hack. Wenn bei deinem Browser das anklicken von Links nicht geht und du sie stattdessen in die Adressleiste kopierst, dann ist das ein Workaround, auch wenn das kopieren von Adressen in die Adressleiste ne ganz normale Funktion ist.


  • Administrator

    Jester schrieb:

    Dravere schrieb:

    Das ist kein Hack, das ist kein hinbiegen, das ist nur ein Nutzen von Features.

    Hast Du grad mal ein Beispiel für einen Hack, der nicht nur das Nutzen von Features beinhaltet?

    Sicher, wenn zum Beispiel jemand Kompilerspezifische Eigenschaft für das Lösen eines Problems heranzieht. Dann nutzt er nicht die Features der Sprache, sondern geht irgendwelche Umwege über den Kompiler und seine Eigenschaften.

    Schnellgeschwindigkeit schrieb:

    Dravere schrieb:

    Der "Small Object Allocator" nutzt einfach die Sprachmöglichkeiten für die eigene Speicherverwaltung. Das ist kein Hack, das ist kein hinbiegen, das ist nur ein Nutzen von Features.

    Workaround bedeutet auch nicht Hack. Wenn bei deinem Browser das anklicken von Links nicht geht und du sie stattdessen in die Adressleiste kopierst, dann ist das ein Workaround, auch wenn das kopieren von Adressen in die Adressleiste ne ganz normale Funktion ist.

    Meilenweiter Unterschied.
    Das Feature ist extra und nur dafür da, dass man Einfluss auf die Speicherverwaltung nehmen kann. Um es mit deinem Beispiel mit den Links aufzuzeigen:
    Links sind anklickbar und per Default öffnet sich ein neues Fenster, in welchem die Seite des Links erscheint.
    Das Feature ist jetzt, dass du diese Funktionalität abändern kannst. Dadurch wird nicht nur ein neues Fenster geöffnet, sondern auch noch ein Meep ausgegeben. Oder was auch immer du machen willst.

    Es ist eben die Möglichkeit die Speicherverwaltung direkt anzupassen. Man geht keine Umwege, man ändert einfach nur das Standardverhalten.

    Grüssli



  • Ob "kleine Speicherbereiche auf dem Heap anfordern" "standardmässig schnell" ist, oder nicht, hängt nur davon ab, welchen Allocator die Implementierung verwendet. z.B. tcmalloc (nur ein Beispiel) ist ziemlich flott. Da ist es weder notwendig noch sinnvoll einen eigenen "small object allocator" zu schreiben, da die Chancen hoch sind, dass dieser langsamer sein wird, als tcmalloc.
    Beim Windows XP Allocator hingegen macht es sinn, da dieser an Lahmheit schwer zu überbieten ist.

    ----

    Als Workaround würde ich aber auch eher ansehen, wenn man ganze Objekte "poolen" muss, weil man eben keine Möglichkeit hat, den Allocator auszutauschen. Wie eben in Java, C#, ...



  • hustbaer schrieb:

    Windows XP Allocator

    was meinste denn damit?
    🙂



  • Schnellgeschwindigkeit schrieb:

    rapso schrieb:

    Schnellgeschwindigkeit schrieb:

    rapso schrieb:

    Schnellgeschwindigkeit schrieb:

    volkard schrieb:

    Kleine Speicherbereiche auf dem Heap anfordern

    siehe "small object allocator" , zum beispiel in "modern c++ design" von alexandrescu.

    natürlich kann man sich nen workaround bauen, aber standardmäßig ist es nicht gerade schnell.

    Das ist eine optimierung, kein work around. Du ersetzt einen algorithmus durch einen besseren. bei java musst du work-arounds einbauen z.b. garnicht allokieren zur laufzeit (ueblich auf vielen handy/smartphones) oder eigene free/alloc listen, weil du garnicht optimieren kannst und bei den einfachsten dingen ploetzlich einen furtchbar langen GC einspringen siehst.... oder im schlimmsten fall garnichts davno weisst.

    Das ist eine optimierung, kein work around. 😃 :p

    anderer meinung? work around ist fuer mich wenn man nicht ohne das auskommt worum man drum arbeitet, es also noch beibehalten muss. aber belehre mich des besseren 😉

    Sind natürlich beides workarounds, weil nicht das Problem da gelöst wird, wo es auftritt, sondern eine eigene Speicherverwaltung verwendet wird, um die standard Speicherverwaltung zu umgehen.

    das problem tritt beim speicherverwalten auf, deswegen loest man es dort. klar koenntest du bei c++ auch pro klasse das new ueberladen, falls du einen dedizierten allokator haben willst, aber meistens ist es halt speichereffizienter einen einzigen globalen pool zu haben, statt viele kleine mit ihrem overhead, denn am ende allokierst du nunmal nur speicher und nicht objekte, die objekte werden nachtraeglich im speicherblock initialisiert.
    von daher sehe ich das als loesung an der richtigen stelle, wobei, wenn es dir nicht gefaellt, du jede andere stelle bei c++ nehmen kannst.
    aber fuer den fall dass ich dich nur nicht verstehe: wie sehe denn in diesem fall deine idealloesung aus fuer dich (wenn du alle moeglichkeiten haettest die eine sprache liefern kann)?



  • +fricky schrieb:

    hustbaer schrieb:

    Windows XP Allocator

    was meinste denn damit?
    🙂

    Das was dasteht: den Allocator von Windows XP. HeapAlloc().

    Das was im Endeffekt die meisten (unmanaged) Windows Programme verwenden, auch wenns als malloc/new/... getarnt daherkommt.



  • hustbaer schrieb:

    +fricky schrieb:

    hustbaer schrieb:

    Windows XP Allocator

    was meinste denn damit?
    🙂

    Das was dasteht: den Allocator von Windows XP. HeapAlloc().
    Das was im Endeffekt die meisten (unmanaged) Windows Programme verwenden, auch wenns als malloc/new/... getarnt daherkommt.

    Komisch. Ich habe immer nur VirtualAlloc genommen, wenn ich new/delete mal reimplementieren wollte.
    Yu beachten ist, dass malloc/free fuer groessere Speicherbereiche optimiert sein sollten als new/delete. Weil man in C nicht dauernd jedes Fityelchen auf den Heap stopft, sondern groerssere Bereiche allokiert und dann vollmacht. In C++ hats wegen der Polzmorphie mehr Bedarf an klityekleinen Allokierungen. Deswegen ist auch davon ausyugehen, dass inywischen jeder ordentliche compiler hinter new/delete eine optimierung fuer small objects hat.
    trotydem ist es immer moeglich, irgend eine standardimplementierung plattyumachen, indem man yusatywissen einbringt.

    yum beispiel koennte ich wissen, und das ist gar nicht mal so unrealistisch, dass waehrend des programmlaufs NIE signifikant viel speicher freigegeben und freigelassen wird und dass nur ein thread eryeugt wird und dass kein objekt groesser als 64k eryeugt wird.
    was machen wir? na, einen buddy-allokator, der bei bedarf vom bs speicher holt, aber nicht ans bs yurueckgibt, der erst bei bedarf defragmentiert und der keine critsects hat. speedup gegenueber normalem new/delete beim MSVC6 war faktor 70. natuerlich ist auch gegen aktuelle compiler ein speedup drin, weil das normale new/delete laufend defragmentieren und ans bs yurueckgeben MUSS. pech gehabt.

    daneben gibt es trotydem noch bedarf an small object allocators fuer diesen oder jenen fall.



  • wow, probleme mit der tastaturbelegung? 🙂



  • Kleine Speicherbereiche auf dem Heap anfordern

    Das ist kein Programm, zumindestens kein sinnvolles.



  • volkard schrieb:

    was machen wir? na, einen buddy-allokator, der bei bedarf vom bs speicher holt, aber nicht ans bs yurueckgibt, der erst bei bedarf defragmentiert und der keine critsects hat. speedup gegenueber normalem new/delete beim MSVC6 war faktor 70. natuerlich ist auch gegen aktuelle compiler ein speedup drin, weil das normale new/delete laufend defragmentieren und ans bs yurueckgeben MUSS. pech gehabt.

    Du hast also einen GC implementiert und den GC-Teil weggelassen 😃



  • knivil schrieb:

    Kleine Speicherbereiche auf dem Heap anfordern

    Das ist kein Programm, zumindestens kein sinnvolles.

    das ist C++ *grins*
    🙂



  • volkard schrieb:

    Gregor schrieb:

    Es ist auch heute noch möglich, äquivalente Programme in C++ und Java zu schreiben, die in Java vielleicht um einen Faktor 5 langsamer sind. Umgekehrt ist das sicherlich auch möglich, aber wesentlich schwerer.

    dazu müßtest du eine konkrete und durch den programmierer nicht behebbare deutliche performance-schwäche von c++ finden. ich bezweifle, daß es die gibt.

    Hier ging doch die ganze Heap, Memory ... Diskussion los. Leider wird in Java anders programmiert als in C++. Letztendlich werden Probleme geloest und zwar in beiden Sprachen unterschiedlich. Deswegen finde ich den Vergleich zwischen Speicherallokationen beider Sprachen hirnlos. Es ist ja auch nichtmal Gegenstand der Sprache sondern der Umgebung. Nur weil diese Hacks/Tricks/Optimierungen vom Benutzer in der JavaVM versteckt sind, heisst das auch noch lange nicht, C++ darf sie nicht verwenden.



  • knivil schrieb:

    volkard schrieb:

    Gregor schrieb:

    Es ist auch heute noch möglich, äquivalente Programme in C++ und Java zu schreiben, die in Java vielleicht um einen Faktor 5 langsamer sind. Umgekehrt ist das sicherlich auch möglich, aber wesentlich schwerer.

    dazu müßtest du eine konkrete und durch den programmierer nicht behebbare deutliche performance-schwäche von c++ finden. ich bezweifle, daß es die gibt.

    Hier ging doch die ganze Heap, Memory ... Diskussion los. Leider wird in Java anders programmiert als in C++. Letztendlich werden Probleme geloest und zwar in beiden Sprachen unterschiedlich.

    das problem ist eher, dass du in java diese probleme nicht loesen kannst, denn die sprache gibt dir darauf keinen zugriff.

    Deswegen finde ich den Vergleich zwischen Speicherallokationen beider Sprachen hirnlos. Es ist ja auch nichtmal Gegenstand der Sprache sondern der Umgebung.

    die sprache java kennt per definition keine speicherbereiche ;). somit ist das ein sprachenunterschied.

    Nur weil diese Hacks/Tricks/Optimierungen vom Benutzer in der JavaVM versteckt sind, heisst das auch noch lange nicht, C++ darf sie nicht verwenden.

    es ist ja der umgedrehte fall der angeprangert wird. in c++ kannst du optimierungen machen fuers speichermanagement, und diese bringen uU sehr viel performance und stabilitaet bezogen auf das laufzeitverhalten.



  • In Java kann man diese Optimierungen auch machen. Dort sind es dann aber wirklich Hacks, z.B. globale (statische) Arrays ... so sollte man nicht in Java programmieren.

    das problem ist eher, dass du in java diese probleme nicht loesen kannst

    Fuer mich ist das kein Problem, ich schreibe meine Anwendung einfach anders. Ich schreibe Programme angepasst an die "Aufgabenstellung"/Spezifikation.

    Man kann nicht erwarten, dass eine C++ uebersetzt nach Java genauso performant ist. Man kann nicht erwarten, dass Java uebersetzt nach C++ genauso performant ist (obwohl die Chancen hier besser sind). Genauso wenig kann man erwarten, dass ein englisches Buch ins Deutsche mittels Tool automatisch uebersetzt genauso toll ist. Will man Wortwitz etc. erhalten, dann muss man sich anders ausdruecken. Nichts anderes.



  • audacia schrieb:

    Du hast also einen GC implementiert und den GC-Teil weggelassen 😃

    eigentlich habe ich nur weggelassen, den speicher ans BS wieder zurueckzugeben, sondern ich habe ihn im programm behalten. innerhalb des programms habe ich freigegeben und ihn neuen objekten zur verfuegung gestellt.
    ich habe gehoert, die java VM behaelt den speicher auch gerne mal eine kleine weile (hack/trick/optimierung) und gibt ihn nicht dem BS zurueck, und das ist eigentlich recht unfair in den kuenstlichen benchmarks. 🤡



  • recht unfair in den kuenstlichen benchmarks.

    Tja, wir vergleichen halt gern den Geschmack von Aepfeln mit Birnen. Btw. die STL trickst da auch.



  • knivil schrieb:

    Fuer mich ist das kein Problem, ich schreibe meine Anwendung einfach anders. Ich schreibe Programme angepasst an die "Aufgabenstellung"/Spezifikation.

    Cool, du kannst Daten sich in Luft auflösen lassen?



  • @volkard:
    VirtualAlloc nimmt man, wenn man *selbst* einen Allocator (z.B. Heap) implementieren möchte. Aber sicher nicht wenn man schnell mal 200 Byte braucht, denn das wäre langsam und verschwenderisch Ende nie.

    Yu beachten ist, dass malloc/free fuer groessere Speicherbereiche optimiert sein sollten als new/delete.

    Auf vielen Systemen ruft new einfach malloc auf. Ist auch vollkommen OK.

    yum beispiel koennte ich wissen, und das ist gar nicht mal so unrealistisch, dass waehrend des programmlaufs NIE signifikant viel speicher freigegeben und freigelassen wird und dass nur ein thread eryeugt wird und dass kein objekt groesser als 64k eryeugt wird.
    was machen wir? na, einen buddy-allokator, der bei bedarf vom bs speicher holt, aber nicht ans bs yurueckgibt, der erst bei bedarf defragmentiert und der keine critsects hat. speedup gegenueber normalem new/delete beim MSVC6 war faktor 70. natuerlich ist auch gegen aktuelle compiler ein speedup drin, weil das normale new/delete laufend defragmentieren und ans bs yurueckgeben MUSS. pech gehabt.

    Vergleich deinen Buddy-Allocator mal gegen tcmalloc. Würde mich interessieren, wer da schneller ist. > 60% der Zeit die der Windows XP Allocator (bzw. auch der MSVC Allocator) brauchen, kommt schonmal vom enter/leave der CRITICAL_SECTION. tcmalloc vermeidet beim überwiegenden Grossteil aller Aufrufe jegliche Synchronisation, da jeder Thread eigene kleine Freelists bekommt. Weiters gibt es getrennte Freelists für bestimmte kleine Grössen wie 2, 4, 8, 12, 16, 20, 24 ... Bytes. Das "Defragmentieren" dieser kleinen Stückchen ist auch so billig dass es nicht weiter ins Gewicht fällt. Uswusf.

    Der einzige echte Nachteil dem man so einem Allocator nachsagen könnte, ist, dass er in vielen Fällen etwas mehr Speicher verbraucht als ein einfacher Heap. Und in seltenen Fällen deutlich mehr Speicher. Lässt sich natürlich auch in gewissen Grenzen steuern, aber je weniger Memory-Overhead man erlaubt, desto langsamer wird wieder alles werden.
    Gerade wo wir langsam aber sicher in Richtung "alles 64" gehen ist das denke ich nicht so schlimm.



  • volkard schrieb:

    ich habe gehoert, die java VM behaelt den speicher auch gerne mal eine kleine weile (hack/trick/optimierung) und gibt ihn nicht dem BS zurueck, und das ist eigentlich recht unfair in den kuenstlichen benchmarks. 🤡

    Wieso sollte man Speicher jemals ans OS zurückgeben? OK, auf einigen Plattformen ist das vermutlich sogar sehr wichtig. Aber auf Windows/Linux/BSD/... ??? Das OS trimmt doch sowieso automatisch das Working-Set, da scher' ich mich doch nicht irgendwas zurückzugeben 🙂



  • hustbaer schrieb:

    volkard schrieb:

    ich habe gehoert, die java VM behaelt den speicher auch gerne mal eine kleine weile (hack/trick/optimierung) und gibt ihn nicht dem BS zurueck, und das ist eigentlich recht unfair in den kuenstlichen benchmarks. 🤡

    Wieso sollte man Speicher jemals ans OS zurückgeben? OK, auf einigen Plattformen ist das vermutlich sogar sehr wichtig. Aber auf Windows/Linux/BSD/... ??? Das OS trimmt doch sowieso automatisch das Working-Set, da scher' ich mich doch nicht irgendwas zurückzugeben 🙂

    Das dachten sich die Programmierer von Company of Heroes auch und ich als Leidtragender darf auf meinem 32Bit OS regelmäßig das Programm neustarten, weil es bei längeren Spielen so viel Müll ansammelt, dass es den maximal zulässigen Anwendungsspeicher von 3GB unter Windows überschreitet. Super weiter so 👍


Anmelden zum Antworten