python 2.5.x memory management

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

BlackJack hat geschrieben:@Dauerbaustelle: Iiih jetzt benutzt Du auch noch `__magic__` in Deiner `fromfile()`. Gibt es einen Grund warum Du die nicht als `classmethod()` "deklarierst"?
Hoorks, weiß auch nicht was ich da geschrieben hatte o__O

Muss natürlich so lauten:

Code: Alles auswählen

class Volume(object):
    cache = dict()

    @staticmethod
    def generate_cache_key(...):
        return unique cache key

    @classmethod
    def fromfile(cls, filename, ...):
        cache_key = cls.generate_cache_key(filename, ...)
        cached_volume = cls.cache.get(cache_key)
        if cached_volume is None:
            cached_volume = cls.cache[cache_key] = cls(...)
        return cached_volume
PS: Das "auch" suggeriert mir, dass der Rest auch bescheiden ist. Irre ich mich da und wenn nein, was ich schlecht daran? :-)
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

meine singleton klasse sieht so aus
vergesst mal die ;

Code: Alles auswählen

class Singleton(object):
    """
    Singleton: Abstract class used for singleton classes. Most children will be used for efficient memory management to speed up things. 
    """
    
    def __new__(cls, *a, **k):
        if not hasattr(cls, '_inst'):
            cls._inst = super(Singleton, cls).__new__(cls, *a, **k);
            
        return cls._inst;
http://de.wikipedia.org/wiki/Singleton_ ... rg-Pattern

Unterschied zu Borg? Mag sein dass ich beim Suchen nach Singleton Mustern zufaellig das Borg muster implementiert hab, zumindest find ich beim googlen grad den gleichen konstrukor dafuer.

So wie ich das verstehe sind dann nach aussen verschiedene objekte die sich aber nach innen den speicher teilen. oder?
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

korrektur

mein source und der borg source sind unterschiedlich.
sorry, mach das hier mit nur einem auge.

trotzdem hab ich immernoch unwissen zum borg pattern

zusaetzliche frage
implementiert object dann auch Borg ?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

thomas15 hat geschrieben:zusaetzliche frage
implementiert object dann auch Borg ?
Wie meinst du die Frage?

Zu deinem eigentlich Problem: Speicher deine Daten einfach in einer Klassenvariable. Klassen sind immer Singletons.
BlackJack

@Dauerbaustelle: Nein das "auch" bezog sich darauf das Du neben dem OP jetzt auch noch __magic__ verwendest. Ist vielleicht ansteckend. :-)

@thomas: Beim Borg-Muster hat man zwar unterschiedliche Objekte, die aber alle den gleichen Zustand teilen. Ist in Python halt einfacher weil man kein `__new__()` braucht. Das ist eher etwas "exotisch".

IMHO ist das einfachste aber immer noch das "Singleton" dadurch zu erreichen, dass man ganz einfach nur ein Exemplar davon erstellt und das dann verwendet. Damit lässt man sich auch die Flexibilität bei Bedarf eben doch mehr als eins zu erzeugen. Denn gerade dieser Fall hier gibt das ja gar nicht zwingend vor.

`object` ist kein "Borg", aber zumindest bei Python 2.x sollte man davon erben statt von "nichts", damit man eine "new style" Klasse bekommt. Auf den "old style"-Klassen funktionieren zum Beispiel "properties" nicht.

Die Doku in dem Singleton und auch der andere Quelltext und Deine Fragen machen ein wenig den Eindruck als wenn Du viel zu viel Gewicht auf Speicherverbrauch und Geschwindigkeit legst. Und zwar ohne den tatsächlichen Bedarf dafür festgestellt zu haben. Du produzierst "hässlichen" weil "unpythonischen" Quelltext in der *vagen Hoffnung* das wäre schneller. Selbst wenn, sind das alles nur Mikrooptimierungen, die ganz locker von so umständlichem Code wie in der gezeigten `get()`-Methoden um ein Vielfaches überschattet wird.
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

Die Doku in dem Singleton und auch der andere Quelltext und Deine Fragen machen ein wenig den Eindruck als wenn Du viel zu viel Gewicht auf Speicherverbrauch und Geschwindigkeit legst.
stimmt. man kann nie zuviel gewicht auf speicherverbrauch und geschwindigkeit legen.
je schneller das ergebniss da ist umso frueher kann ich in den biergarten.
Du produzierst "hässlichen" weil "unpythonischen" Quelltext in der *vagen Hoffnung* das wäre schneller.
Verbrennt mich :D
auf "unpythonische" art und weise
:D :D :D

nichts fuer ungut, ich werd mir bei gelegenheit euere vorschlaege in ruhe anschauen und wenns passt implementieren.

danke und gruss an alle die sich beteiligt haben.
hiermit beende ich das thema

;
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@thomas15 Deine wage Hoffnung ist nur unbegründet. Man kann in der Regel davon ausgehen das pythonischer Code schneller ist als irgendwelche Konstrukte von denen man naiv ausgeht sie könnten schneller sein.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

thomas15 hat geschrieben:stimmt. man kann nie zuviel gewicht auf speicherverbrauch und geschwindigkeit legen.
je schneller das ergebniss da ist umso frueher kann ich in den biergarten.
Dann nimm C++. Nein, mal im Ernst, wenn du versuchst Problemfälle zu optimieren die (noch) nicht existieren kommst du nie in den Biergarten.

Und zum „zuviel in C denken“: Auch in C wird, sobald das Programm durchgelaufen ist, der Speicher wieder freigegeben.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Darii hat geschrieben:
thomas15 hat geschrieben:stimmt. man kann nie zuviel gewicht auf speicherverbrauch und geschwindigkeit legen.
je schneller das ergebniss da ist umso frueher kann ich in den biergarten.
Dann nimm C++. Nein, mal im Ernst, [...]
So abwegig ist deine Aussage doch gar nicht. Der OP scheint sich offensichtlich nicht für Eleganz, sondern hauptsächlich für Speicherverbrauch und Geschwindigkeit zu interessieren. Ich denke nicht, dass Python ihm da dauerhaft nutzen wird. Als einzigen Vorteil käme dann wirklich nur (abhängig vom Einzelfall) die Portabilität und der eingebaute Compiler zum Tragen. Allerdings würde es mich ehrlich gesagt nicht wundern, wenn bald ein Thread kommt, wie man die tollen speicheroptimierten Skripte als EXE ausliefern kann. Und ja, ich hab eine vorurteilsbehaftete Abneigung gegen solche Python-Programmierer. :lol:
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

@snafu

ok, jetzt entgleitet die topic mittlerweile, aber die designfrage hier ist natuerlich das ausschlaggebende.
du / ihr habt recht zu sagen dass C++ besser sei was performanz angeht, keine frage.
in der akademie ist es -zumindest in meinem feld- zZ beliebt toplevel scripting ala python zu entwickeln damit man schnell zu funktionierenden loesungen kommt , wobei man schnellen C++ code interfaced. ausserdem moechte man ja seine toolboxen weiterverbreiten, und da ist bedienbarkeit fuer leien sehr wichtig.
ich ware lieber auch fuer C++, aber die designfrage habe ich nicht mitbestimmen koennen, also lebe ich damit. kann sein dass meine optimierungen zu brute force sind und vielleicht nix bringen, aber jetzt hab ich was gelernt.

wie auch immer, mein singleton konstrukt (oder sollte ich es zum borg konvertieren - alternativen wirds viele geben) ist an der stelle genau richtig. fuer mich ist halt das speicherverhalten von python, insbesondere mit swig ein wenig schleierhaft. muss sagen dass objective c (mit retain, release, copy...) da wohl aehnlich ist, aber in meinen augen besser dokumentiert. aja, wenns program endet dann ist alles freigegeben, klaro.

wenn ich so rausschau ist heute wohl kein biergartenwetter.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

thomas15 hat geschrieben:wie auch immer, mein singleton konstrukt (oder sollte ich es zum borg konvertieren - alternativen wirds viele geben) ist an der stelle genau richtig.
Du brauchst da kein Singleton. Einfach den Cache als Klassenvariable und eine Factory als Klassenmethode, wie Dauerbaustelle das schon vorgeschlagen hatte.
fuer mich ist halt das speicherverhalten von python, insbesondere mit swig ein wenig schleierhaft.
Python ist einfach eine 0815-Hochsprache mit automatischer Speicherverwaltung. D.h. du musst dich prinzipiell um nichts kümmern. Sobald ein Objekt nicht mehr sichtbar ist, d.h nirgends mehr referenziert wird, wird es freigegeben.
muss sagen dass objective c (mit retain, release, copy...) da wohl aehnlich ist, aber in meinen augen besser dokumentiert.
Nein, das ist völlig anders. Bei Objective C (ohne garbage-collector) betreibst du manuelles Speichermanagment wie in C auch. Der einzige Unterschied ist, dass dich das Framework(nicht die Sprache!) dabei unterstützt indem es Methoden zur Speicherverwaltung bereitstellt.

Zudem musst du bei ObjC aufpassen, da dort reine Referenzzählung betrieben wird, ist es anfällig für zyklische Referenzen. Deswegen gibt es zusätzlich noch sog. Autorelease-Pools die das verhindern(außerdem sind sie die einzige Möglichkeit in bestimmten Fällen Objekte zurückzugeben ohne sie zu leaken).

edit: ich sehe gerade du sprachst swig an, ja das C-API-Interface ist ähnlich zu ObjC(bis auf die Abwesenheit eines Autorelease-Pools), so lange man http://docs.python.org/extending/extend ... ship-rules beachtet sollte man da in Python aber keine Probleme kriegen.
Zuletzt geändert von Darii am Freitag 30. April 2010, 09:50, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Kontrollierte Speicherverwaltung ist nun mal kein Feature der Sprache. Wenn man `del` benutzt, dann eigentlich nur, um etwas aus dem Namensraum, aus einer Liste (manche ziehen hier pop() vor), usw zu bekommen, aber nicht weil man vor hat, exakt im Moment des Aufrufs Speicher freizugeben. Du wirst dich da wohl dran gewöhnen müssen.
Darii hat geschrieben:Python ist einfach eine 0815-Hochsprache
:evil: :evil: :evil:
;)
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

Python ist einfach eine 0815-Hochsprache mit automatischer Speicherverwaltung. D.h. du musst dich prinzipiell um nichts kümmern. Sobald ein Objekt nicht mehr sichtbar ist, d.h nirgends mehr referenziert wird, wird es freigegeben.

ok, ich hab eingesehen ein singleton durch anderes ersetzbar ist, bin aber nicht sicher ob eine alternative dann gleich performt.

also, der ablauf ist wie folgt


read(file,x,y,z)
-> cache objekt nicht existent, wird angelegt
-> file mit parametern ist nicht in cache objekt -> wird gelesen, gefiltert, gecached, zurueckgegeben
-> read zu ende, KEINE referenz mehr auf cache objekt

was nun in meinen augen ohne singleton passiert:
cache wird freigegeben, inklusive aller files

2. read(file,x,y,z) (ohne singleton)
-> cache objekt nicht existent, wird angelegt
-> file mit parametern ist nicht in cache objekt -> wird gelesen, gefiltert, gecached, zurueckgegeben
-> read zu ende, keine referenz mehr auf cache objekt
bei wiederholung wird die file nochmals gelesen, gefiltert usw.

2. read(file,x,y,z) (mit singleton)
-> cache objekt existent noch, wird nicht erneut angelegt, alle files sind noch im speicher
-> file mit parametern ist im cache objekt -> wird nicht gelesen, sondern gleich zurueckgegeben
-> read zu ende, referenz bleibt auf cache objekt, deshalb auch alle anderen files
kann den teil 10000x wiederholen ohne die gleiche file mehrmals zu lesen und zu filtern

vorteil von dem code: ich muss das cache objekt nicht an der hand halten bis ich es wieder brauche.
es bleibt im speicher, kommt bei bedarf und verschwindet dann wieder, bleibt aber mit seinem aktuellem zustand.
welche patterns in python koennen das? ein borg?
merke, ich halte keine weiteren referenzen mehr auf den cache.

bitte meinungen.
BlackJack

@thomas15: Der Vorschlag war ja den Cache nicht in der `read()` erstellen sondern ausserhalb davon, sozusagen "statisch". Entweder als Cache-Objekt auf das von der `read()` aus zugegriffen wird, oder den Cache und das `read()` in einem Objekt kombiniert. Wäre mein Favorit, weil das IMHO eng genug verzahnt ist, dass man es in ein Objekt stecken kann.
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

hi,


ja, dann waers moeglich das ohne singletons zu loesen, einverstanden.

der nachteil ist aber wenn ich die read(mit cache) zum test (oder warum auch immer) durch die gewoehnliche read (einfach nur lesen) austauschen will muss ich den code mit anpassen. so passiert alles in der read intern und der benutzer schert sich um nichts mehr im code.
die funktion lauft wie die gewoehnliche read, nur dass sie inteligenter ist als die andere.
BlackJack

@thomas15: Wie geht dass denn auf magische Weise? Du musst doch so oder so irgendwo am Quelltext was ändern um den Cache zu (de)aktivieren. Die Frage ist halt nur an welcher Stelle.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

thomas15 hat geschrieben:ok, ich hab eingesehen ein singleton durch anderes ersetzbar ist, bin aber nicht sicher ob eine alternative dann gleich performt..
Nochmal: Eine Klasse *ist* ein Singleton. Alternativ kannst du den Cache auch in einer globalen Variable speichern, das kommt aufs selbe hinaus, weil Module auch Singletons sind. Aber eine normale Instanz würde es auch tun.
thomas15 hat geschrieben:der nachteil ist aber wenn ich die read(mit cache) zum test (oder warum auch immer) durch die gewoehnliche read (einfach nur lesen) austauschen will muss ich den code mit anpassen. so passiert alles in der read intern und der benutzer schert sich um nichts mehr im code.
die funktion lauft wie die gewoehnliche read, nur dass sie inteligenter ist als die andere.
Ich weiß nicht, was du damit meinst, aber ich habe das Gefühl das du da wieder irgendwo ein Problem siehst, dass einfach nicht existiert.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

thomas15, die Annahme, dass keine Referenz mehr auf das gecachete Objekt besteht, ist falsch. In meiner Lösung zum Beispiel wird IMMER eine Referenz auf alle gecacheten Objekte bleiben, solange das Cache-Dictionary besteht, und das tut es während dem ganzen Programmablauf.
Antworten