# Häufigkeit eines Zeichens ermitteln



## deamon (23. Jul 2009)

Ich will herausfinden, wie oft ein bestimmtes Zeichen in einem String vorkommt.

Das Beste, was mir eingefallen ist, ist die Umwandlung in ein char-Array und dann ein zeichenweiser Vergleich in einer Schleife. Gibt es dafür auch eine bestehende Methode?


----------



## Ark (23. Jul 2009)

Nein, aber es gibt [c]String.charAt(int)[/c] nebst [c]String.codepointAt(int)[/c], was die Umwandlung in ein char-Array überflüssig machen sollte.

Ark


----------



## deamon (23. Jul 2009)

Aber ist das auch schneller oder zumindest gleich schnell? Es geht um einen Bereich, wo es auf die Performance ankommt.


----------



## L-ectron-X (23. Jul 2009)

...kommt es das nicht immer? Wer möchte schon gerne ineffiziente Programme schreiben/benutzen?


----------



## Ark (23. Jul 2009)

deamon hat gesagt.:


> Aber ist das auch schneller oder zumindest gleich schnell?


Das Erzeugen des Arrays kostet auch Zeit. 

Wenn es dir um Geschwindigkeit geht, solltest du dir vor allem das Design vorknöpfen. Meine bisherigen Erfahrungen zeigten, dass Strings kaum dazu geeignet sind, komplexe Strukturen darzustellen. Ich entwarf deshalb meist eigene, und das führte dazu, dass ich eben so etwas wie "Zählen von Zeichen in String" nie brauchte und wohl auch nie brauchen werde.

In Strukturen, bei denen es auf Performance ankommt, habe ich höchst selten Strings gesehen, und das aus einem guten Grund: Strings sind nicht dazu geschaffen, Daten in einer für die Maschine aufbereiteten Form zugänglich zu machen. Sie sind eher dazu gedacht, eine rein auf Text basierende Schnittstelle vor allem zu Menschen zu ermöglichen. In Schichten sehr hoher Abstraktion haben Strings selten etwas zu suchen, und wenn, dann werden nur Zeiger auf sie ausgetauscht, aber es wird nie auf den Strings gearbeitet.

Faustregel: String-Operationen sind inhärent langsam.

Ark


----------



## deamon (23. Jul 2009)

Ark hat gesagt.:


> Das Erzeugen des Arrays kostet auch Zeit.



Ein wichtiger Punkt! Wie es scheint sogar der entscheindende, denn der Gewinner ist ganz klar die Variante mit charAt(index).

Falls sich jemand über den komischen Java-Code wundert, das ist Scala ;-)

```
// 32 Millisekunden für 1 Mio aufrufe
def countCharAt(subject: String, c: Char)={
	var index = subject.length - 1
	var count = 0
	while(index >= 0){
		if(subject.charAt(index) == c) count += 1
		index -= 1
	}
	count
}

// 328 Millisekunden für 1 Mio aufrufe
def countArray(subject: String, c: Char)={
	var count = 0
	for(character <- subject.toCharArray)
		if(character == c) count += 1
	count
}

// 62 Millisekunden für 1 Mio aufrufe
def countCharAt(subject: String, c: Char)={
	var index = subject.length - 1
	val characters = subject.toCharArray
	var count = 0
	while(index >= 0){
		if(characters(index) == c) count += 1
		index -= 1
	}
	count
}
```

Etwas irritiert mich, wie brutal langsam die Variante mit der for-Schleife ist, aber da muss zum einen ein CharArray erzeugt werden und dann wird auch noch bei jedem Aufruf ein Char-Objekt erzeugt, das scheint teuer zu sein.



Ark hat gesagt.:


> Wenn es dir um Geschwindigkeit geht, solltest du dir vor allem das Design vorknöpfen. Meine bisherigen Erfahrungen zeigten, dass Strings kaum dazu geeignet sind, komplexe Strukturen darzustellen. Ich entwarf deshalb meist eigene, und das führte dazu, dass ich eben so etwas wie "Zählen von Zeichen in String" nie brauchte und wohl auch nie brauchen werde.



Wenn es um ein abstraktes Problem ginge, wäre ich geneigt, dir zu zustimmen. Aber in diesem Fall kommen die Daten nur per String rein (über das Netz) und daran kann ich auch nichts ändern, solange das HTT-Protokoll von anderen festgelegt wird ;-)

Also vielen Dank für deinen Hinweis mit charAt! Ich hätte es vermutlich mit einem Array wesentlich weniger performant umgesetzt.


----------

