![]() |
Record komplett oder nur teilwese kopieren?
Hallo,
Wer keine Lust hat sich die hintergründe durch zu lesen kann gleich bis zum Source: "Variante1:" scrollen ich steh vor nem kleinen Problem. Es schreib an einer MusicSoftware die mehrere Playlisten hat. Wenn ein Lied gespielt wurde soll dies natürlich in allen Listen angezeigt werden und nicht nur in der wo es gespielt wurde. Deswegen hab ich eine Hauptplayliste und viele Normale Playlisten welche auf die Hauptplayliste verweisen. Wird ein neues Lied zu irgend einer Playliste hinzugefügt, wird es nur in der Hauptplayliste erstellt. In der eigentlichen Playliste wird dann der gleiche Record angelegt und die Items darin zeigen dann auf die Items der Hauptliste (siehe sourceschnipsel)
Delphi-Quellcode:
Nun zum eigentlichen Problem. Wenn ich ein Lied aus irgend einer Playliste in eine andere kopiere, ist es ja das einfachste einfach das Item(den Record) aus der Hauptliste zu kopieren.
PBoolean = ^Boolean;
PString = ^String; PInteger = ^Integer; TJBFileInfo = record Filename: String; FilenameP: PString; //in Hauptliste zeigts auf Filename - In normaler Liste zeigts auf Filename von Hauptliste Interpret: String; InterpretP: PString; Title: String; TitleP: PString; Genre: String; GenreP: PString; FileTime: Integer; FileTimeP: PInteger; AddedBySearch: Boolean; AllreadyPlayed: Boolean; AllreadyPlayedP: PBoolean; IsSelected: Boolean; //legt fest ob das Item selectiert ist oder nicht (deswegen geht auch nicht ein Pointer auf den gesamten Record) end; Dabei würden ja aber auch die Strings und alles mit kopiert werden (ich brauch aber nur die Pointer). Soll ich nun jeden Pointer einzeln kopieren oder den gesamten record? Variante1:
Delphi-Quellcode:
procedure CopieItem(AItem: TJBFileInfo);
var NewItem: TJBFileInfo; begin NewItem := AItem; {NewItem zu Playliste hinzufügen} end; Variante2:
Delphi-Quellcode:
Welche Variante würded ihr nehmen Wenn ihr nur die Pointer aus dem Record braucht?
procedure CopieItem(AItem: TJBFileInfo);
var NewItem: TJBFileInfo; begin NewItem.FilenameP := AItem.FilenameP; NewItem.InterpretP : AItem.InterpretP; NewItem.TitleP : AItem.TitleP; NewItem.GenreP : AItem.GenreP; NewItem.FileTimeP : AItem.FiletimeP; NewItem.AllreadyPlayedP : AItem.AllreadyPlayedP; {NewItem zu Playliste hinzufügen} end; Variante1 = Mehr speicherverbrauch Variante2 = Mehr zuweisungen Oder gibts noch ne dritte effektivere Variante? (keine Kommentare zu "PString = ^String;" - ich weiß selbst das dies ein pointer auf einen Pointer ist) |
Re: Record komplett oder nur teilwese kopieren?
Moin!
Ich würde das etwas anders machen: 1. Ich würde einen Record definieren der alles drinne hat (direkt die Strings & Daten). 2. Dann wurde ich einen Pointer auf den Record als Type definieren 3. Dann würde ich den Record immer nur bei der Hauptliste anlegen/löschen 4. Die anderen Listen bekommen immer nur den Pointer des Records - somit greifen alle Listen auf den selben Record zu 5. Wenn der Record aus einer Liste entfernt werden soll (ausgenommen Hauptliste), dann einfach den Pointer aus der Liste löschen 6. Wenn der Record aus der Hauptliste rausfliegt, dann vorher die anderen Listen nach dem Pointer durchsuchen und dort auch löschen 7. Wenn 6. getan wurde, dann den Record aus der Hauptliste entfernen und freigeben. 8. Zum besseren Arbeiten mit den Listen würde ich eine TList nehmen Ansonsten gibt es zur Verbesserung von 6. noch die Möglichkeit ein dynamisches Array in dem Record zu definieren wo alle Listen eingetragen werden (bis auf die Hauptliste), wo der Eintrag noch hinzugefügt wurde. Damit kannst du 6. einfacher machen und musst nicht mehr suchen, sondern gehst einfach die Liste durch. Du kannst dir die Arbeit mit den Playlisten und den Automatismus mit dem dynamischen Array vereinfachen, wenn du dir einfach eine eigene Ableitung von TList baust, die das denn gleich mit erledigt. Dann kümmert sich diese Liste auch gleich um die ordentliche Entfernung / Addition des Records und um dessen anlegen/freigeben. MfG Muetze1 |
Re: Record komplett oder nur teilwese kopieren?
@Muetze: Punkt2 kann ich nicht verwirklichen weil der Record "IsSelected" beinhaltet. In dieser Variablen wird gespeichert ob das Item selektiert ist oder nicht. Wenn ich jetzt deine Variante nehmen würde wäre das Item in jeder Liste selektiert. somit sind die restlichen Punkte auch hinfällig.
Aus der Hauptliste wird übrigens nie ein Item gelöscht. An alle anderen (die noch nicht gepostet haben). Egal ob ihr Ahnung von der Problematik habt oder nicht, postet bitte trotzdem welche Variante ihr als user bevorzugen würde - Variante1 die schneller ist aber mehr ressourcen braucht oder Variante2 die langsamer ist aber weniger ressourcen benötigt |
Re: Record komplett oder nur teilwese kopieren?
Du solltest deinen Record in eine Klasse umwandeln.
Dann sind Daten und Programmcode beisammen. Du wirst feststellen, dass mit der Zeit immer mehr Funktionen dazukommen, die mit dem Record TJBFileInfo arbeiten. Diese Funktionen (Kopieren, Löschen, Prüfen, ...) sind in einer Klasse (sie heissen dann Methoden) besser aufgehoben. |
Re: Record komplett oder nur teilwese kopieren?
@shmia: Es ist derzeit so gelöst das ich die Records in einer TList organisiere. Die TList wird wiederum von einem Object verwaltet was die Eigenschaft Items hat und somit alles wunderbar verwaltet - es ist also im prinzip schon in einer klasse und geht nur darum wie diese arbeiten soll.
den Record selbst als Klasse zu definieren ist zu unperformant. Teilweise werden über 100 GB MP3s geladen, und wenn jedes mp3-datei eine extra klasse wäre würde sich das schon bemerkbar machen. Außerdem kann es auch möglich sein das diese 100 GB (ca 21 000 Lieder) in 5 Listen sind. Somit hätte ich schon 105 000 Object und diese benötigen mit ihrem Konstructor und allem nicht wenig speicher. Das Konzept ist ansich schon lange genug durchdacht wurden (Liste kann sourcelist haben welche wiederum eine sourceliste hat um den Festplattenzugriff möglichst zu vermeiden). Das klappt derzeit auch alles supi. Mich interessiert nur was der user eher bereit ist zu opfern - Zeit oder Ressourcen - wobei die ressourcen für so einen record sehr gering sind |
Re: Record komplett oder nur teilwese kopieren?
Moin!
Wenn z.B. nur das selected extra hast, dann kann das jede von deiner TList Klasse selber verwalten zu dem Record. Ansonsten ist es wirklich besser, wenn du das zu einer Klasse umformst... MfG Muetze1 |
Re: Record komplett oder nur teilwese kopieren?
Ist doch aber reichlich ressourcenverschwendung wennich aus dem record ein TObject mache, wovon es dann mehrere 10.000 Instanzen gibt. Damit wäre außerdem mein Problem noch nicht, es würde eher noch größer weil der aufruf des Constructors auch wieder speicher benötigt und die cpu belastet, und die zuweisung um die es mir geht würde ja dann trotzdem/weiterhin anfallen
|
Re: Record komplett oder nur teilwese kopieren?
Moin!
Zitat:
Ich schreibe einen Editor für meine Firma und der hat eine Bibliothek. Diese Bibliotheksobjekte sind einzelne Klasseninstanzen und z.T. mit jeweils bis zu 4 Bitmaps und ich habe keine Probleme. Die Anzahl der Objekte geht bis die 25.000 Objekte und es nicht das Ding. Der Speicherverbrauch bei der Anzahl von Objekten bis zu 20 MByte - dabei fällt das meiste aber für die Bitmaps an. Ich musste mir nur damals was schreiben für Win9x/ME um die ganze Anzahl von Bitmap-Handles zu bekommen, das Windows 9x/ME einen festen Bereich für die GDI Handles hat und der zu klein wird für diese Menge an Bitmaps... ;-) MfG Muetze1 |
Re: Record komplett oder nur teilwese kopieren?
wenn ich das ganze in ein object packe dann brauch ich den speicher aber auch + den speicher für das object an sich... außerdem wollt ich ja nur wissen welche Variante ihr bevorzugt. Der Record befindet sich ja schon in einem Object (TJBDataList) und dieses Object hat die eigenschaft Items... Es geht nun darum wenn von einer liste in die andere kopiert werden soll... Deswegen wollt ich eigentlich wissen welche Variante ihr bevorzugen würdet. Denn einfach mal so 20 000 Titel von einer in ne andere Liste zu kopieren braucht schon bissl zeit zumal ja noch geprüft wird ob das object bereits in der Ziellist und in der sourcelist existiert...
Will wirklich nur wissen ob ich lieber die ressourcen verschwenden soll oder lieber mehrere Zuweisungen machen soll was allerdings die cpu mehr belastet (kann mich ni entscheiden) |
Re: Record komplett oder nur teilwese kopieren?
Moin!
Ok, dann eine definitive Antwort von mir: Ich würde mir eine eigene Liste schreiben für die Objekte und die Records als Objekte machen. Und das die Liste da mal schnell dir Objekte beim zuweisen durchläuft und vergleicht ist eh ein geringes Problem. Diesen Vorgang kann man dann immernoch in einen Thread packen und man kann die Playlist dann immernoch ab und zu zur Threadlaufzeit updaten. Daher: Meine Meinung kennst du denn nun... :cyclops: PS: Ich habe ebend noch was hinzueditiert... /EDIT: Bei diesem Editor/Programm für die Arbeit mit den tausenden Instanzen ist es auch so, das es in der Malroutine 8 Schleifen gibt, wo listenweise alle Objekte durchgelaufen werden und gemalt werden und ich habe kein Problem mit der Geschwindigkeit... MfG Muetze1 |
Re: Record komplett oder nur teilwese kopieren?
*heul* die variante die du beschreibst hatte ich bereits und die war zu unperformant. Ich hab sogar meine While schleife durch ne For-schleife ersetzt weil man bei den riesen datenmengen die ich hab den unterschied sonst gewaltig merkt - Deswegen wollte ich ja eigentlich nur wissen ob ihr Variante1 oder Variante2 des ersten posts dieses thread bevorzugt
|
Re: Record komplett oder nur teilwese kopieren?
Moin!
Ok, bevor du heulst... 8) : Beide Methoden machen das gleich, die erste aber schneller. Die erste Variante kopiert den Record aber am Stück mit einem MemCopy und die zweite halt alles einzelnd, somit ist die erste eigentlich schneller. Dann ist die Sache, das die erste Variante nicht bei allen Delphi Versionen funktioniert (ich glaube bei Delphi 4 wurden Elemente eines Records noch nicht mitkopiert bei einer solchen Zuweisung, da musstest du das mit Move() selber machen). Daher ist die Entscheidung bei dir... MfG Muetze1 |
Re: Record komplett oder nur teilwese kopieren?
Also irgendwie scheinst du nicht hingeguckt zu haben. Bei variante1 wird der komplette record kopiert - bei variante2 nur ein Teil davon (weil ich ni alle variablen in der anderen liste benötige). Wenn ich den record komplett in der anderen liste bräuchte wäre die entscheidung schon lange gefallen. Ich will aber eben nur die hälfte der im record befindlichen Dinge in den anderen record kopieren
|
Re: Record komplett oder nur teilwese kopieren?
Moin!
Zitat:
- Wieso mehr Speicherverbrauch bei Variante 1? Der Record ist so oder so in der vollen Grösse angelegt und die Strings sind eh nur Referenzen (zeigen auf den gleichen String), da diese den gleichen Inhalt haben. MfG Muetze1 |
Re: Record komplett oder nur teilwese kopieren?
Hmm, stimmt, daran hatte ich gar ni gedacht das es nur referenzen sind. Wobei es keine referenzen mehr sind wenn der string in der hauptliste geändert wird?! Naja, ich gebs auf - ich lass das thema jezt - das führt zu keinem ergebnis... Solange die strings nur referenzen sind ist die größe ja gleich ansonsten isses halt bissl performance verbrauch
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz