Kurzlebige Objekte Vermeiden
 
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

Von SoftwareOptimierung
Was in der SpracheCee als dynamische Speicherverwaltung mit malloc/free programmiert werden muss, passiert in moderneren und OO Sprachen (wie Java, Python, Perl etc.) automatisch und im Hintergrund. Das bedeutet aber nicht, dass sich durch irgendeinen magischen Effekt die erforderlichen Vorgänge verändern. Es gibt natürlich auch in OO-Sprachen so etwas wie einen "memory pool" oder "heap", dem die benötigten Speicherblöcke entnommen und an den sie wieder zurückgegeben werden. Und die Vorgänge haben auch eine ähnliche Problematik und in Bezug auf Speicherbedarf und Ausführungszeit. Siehe dazu MallocFreeVermeiden.
Will man also in OO-Sprachen effizient programmieren, muss man ein Gefühl dafür entwickeln, welche Vorgänge im Hintergrund ablaufen und wie komplex die verwendeten Objekte sind. Die Regel besagt, dass man - wenn möglich - KurzlebigeObjekteVermeiden soll.

Standardbeispiel

Das Standardbeispiel, wie man mit kurzlebigen Objekten die Performance ruiniert ist uralt und stammt in seiner Ur-Form noch aus alten BASIC-Zeiten (hatte immer schon dynamische Speicherverwaltung und GC bezüglich Strings). Ziel des Beispiels ist der Aufbau einer Zeichenkette aus N (z.B. 1000) Zeichen c$:

' schlechtes Beispiel in BASIC
s$="": c$="*"
FOR i%=1 TO N 
  s$=s$+c$
NEXT

//schlechtes Beispiel in JAVA
String s="", c="*";
for(int i=0; i<N; i++) {
   s = s + c;
}

In beiden Fällen werden um einen einzigen String der gewünschten Länge aufzubauen, in der Größenordnung von N kurzlebige Objekte als Zwischenresultate aufgebaut, nur um sofort wieder zerstört zu werden. Das gleiche Kunststück ist natürlich auch in C möglich, wenn man Speicherbereiche mit realloc Byte-weise vergrößert.

Alternativ dazu könnte man in Java z.B. mit einem StringBuffer entweder so

public static final String StringCreateCharLen(char c,int len) {
  StringBuffer string = new StringBuffer();
  for(int i=0; i<len; i++) {
    string.append(c);
  }
  return string.toString();
}

(etwa log2(len/16) temporäre Arrays im StringBuffer?)

oder so

public static final String StringCreateCharLen(char c,int len) {
  StringBuffer string = new StringBuffer(len); // <--- !!!
  for(int i=0; i<len; i++) {
    string.append(c);
  }
  return string.toString();
}

(keine temporären Arrays)

oder mit:

public static final String StringCreateCharLen(char c,int len) {
  char [] cb=new char[len];
  for(int i=0; i<len; i++) {
    cb[i]=c;
  }
  return new String(cb,0,len);
}

die temporären, kurzlebigen Objekte vermeiden. Der Unterschied ist gewaltig.

Bei häufigerem Gebrauch mit gleichem Zeichen c bietet sich außerdem das Caching (SprachPolizei?) des String(Buffer)s an:

public class CharacterRepeater {
  private char character;
  private StringBuffer concatenation = new StringBuffer();

  public CharacterRepeater(char character) {
    this.character = character;
  }

  public String concatenation(int length) {
    ensureLength(length);
    return concatenation.toString().substring(0, length);
  }

  private void ensureLength(int length) {
    int oldLength = concatenation.toString().length();
    concatentation.ensureCapacity(length);
    for (int l = oldLength; l < concatenation.capacity; l++) {
      concatenation.append(character);
    }
  }
}

Das gleiche als schlechtes Beispiel in SprachePython:
s = ""
c = "*"
for i in range(1000):
    s = s + c
Und danach erheblich verbessert:
import string
l = []
c = "*"
for i in range(1000):
    l.append(c)
s = string.join(l)
Erklärung: Eckige Klammern verwendet Python für Literale vom Type Liste.


Variationen zu diesem Thema:


Ein andere Dimension dieses Problem findet sich bei temporären anonymen Variablen beim Auswerten von Ausdrücken über komplexe Datentypen.


KategorieOptimierung KategorieProgrammierBeispiele
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 26. April 2001 9:38 (diff))
Suchbegriff: gesucht wird
im Titel
im Text