/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Kompleksitet af String operationer
Fra : Martin Ehmsen


Dato : 05-11-01 22:33

Hej alle...

Jeg sidder i øjeblikket og roder lidt med nogle manipulationer af chars.
Disse chars bliver manipuleret og derefter sat sammen til en String på
følgende måde:

String total;
while( derErFlereChars ) {
char c = ...
// Operationer på charen
total += c;
}

Nu er problemet blot det, at jeg i de fleste har temmelig mange chars
at lege med. Typisk > 10000.
Men algoritmen ovenfor bliver langsommere desto flere chars der er
blevet sat på strengen.
Jeg har indsat lidt debugging kode, som tæller antal chars som jeg har
arbejdet med og indsat i total.
De første 1000 chars går hurtigt, men når man kommer over 5000 chars
som er indsat i total så bliver de næste 1000 langsommere og
langsommere.
Jeg har et bud på hvad grunden kan være, men jeg vil lige høre jeres
bud og evt. høre om der nogen smart workaround.
Mit bud på grunden er at internt bliver String's opbevaret som et char
array. Når jeg vil indsætte et nyt tegn først i den gamle String, så er
det ikke sikkert der er plads til at udvide arrayet og derfor kan det
værre at hele arrayet skal kopieres til et nyt sted i hukommelsen og så
indsætte det nye tegn.

Mvh.
Martin Ehmsen
--
"Life is good for only two things,
discovering mathematics and teaching mathematics"
Siméon Poisson

 
 
Mikkel Bundgaard (05-11-2001)
Kommentar
Fra : Mikkel Bundgaard


Dato : 05-11-01 00:01

Martin Ehmsen <thames@get2net.dk> wrote in message
news:9s4c4g$ktt$1@sunsite.dk...
> Hej alle...
>
> Jeg sidder i øjeblikket og roder lidt med nogle manipulationer af
> chars.
> Disse chars bliver manipuleret og derefter sat sammen til en
> String på
> følgende måde:
>
> String total;
> while( derErFlereChars ) {
> char c = ...
> // Operationer på charen
> total += c;
> }
>
> Nu er problemet blot det, at jeg i de fleste har temmelig mange
> chars at lege med. Typisk 10000.
> Men algoritmen ovenfor bliver langsommere desto flere chars
> der er blevet sat på strengen.
<SNIP>
> Mit bud på grunden er at internt bliver String's opbevaret som et
> char array. Når jeg vil indsætte et nyt tegn først i den gamle
> String, så er det ikke sikkert der er plads til at udvide arrayet og
> derfor kan det være at hele arrayet skal kopieres til et nyt sted i
> hukommelsen og så indsætte det nye tegn.
>
> Mvh.
> Martin Ehmsen
Hej Martin

Brug en StringBuffer i stedet for en String som variablen total. Så
kan du i slutningen konvertere StringBufferen til en String.
Problemet med din kode er, at der oprettes et nyt String objekt, for
hver iteration (en meget dyr operation).

Se evt. "Why Two String Classes" fra Sun.
http://java.sun.com/docs/books/tutorial/java/data/whytwo.html

"You typically use string buffers for constructing character data
dynamically: for example, when reading text data from a file.
Because strings are constants, they are more efficient to use than
are string buffers and can be shared".
--
Mikkel Bundgaard
IT University of Copenhagen
http://officehelp.gone.dk
ICQ# 116946261
Se SpaceCommunicator - en peer-to-peer chat-applikation i Java



Jonas Kongslund (05-11-2001)
Kommentar
Fra : Jonas Kongslund


Dato : 05-11-01 00:03

on Monday 05 November 2001 22:33, Martin Ehmsen <thames@get2net.dk> wrote:

> Jeg sidder i øjeblikket og roder lidt med nogle manipulationer af chars.
> Disse chars bliver manipuleret og derefter sat sammen til en String på
> følgende måde:
>
> String total;
> while( derErFlereChars ) {
> char c = ...
> // Operationer på charen
> total += c;
> }

Brug java.lang.StringBuffer.

> Mit bud på grunden er at internt bliver String's opbevaret som et char
> array. Når jeg vil indsætte et nyt tegn først i den gamle String, så er
> det ikke sikkert der er plads til at udvide arrayet og derfor kan det
> værre at hele arrayet skal kopieres til et nyt sted i hukommelsen og så
> indsætte det nye tegn.

Et String-objekt er af hensyn til optimering gjort immutable, dvs. dets
indhold kan ikke ændres. Når du skriver total = total + c så bliver der
oprettet en ny streng i stedet for at rette i total.

--
Jonas Kongslund <jonas(at)kongslund.dk> XNS: =Jonas Kongslund

Digital Rights - raising awareness of rights in the digital world
http://www.digitalrights.dk

Jonas Kongslund (05-11-2001)
Kommentar
Fra : Jonas Kongslund


Dato : 05-11-01 00:29

on Monday 05 November 2001 00:03, Jonas Kongslund <gamma@post.tele.dk>
wrote:

> Et String-objekt er af hensyn til optimering gjort immutable, dvs. dets
> indhold kan ikke ændres. Når du skriver total = total + c så bliver der
> oprettet en ny streng i stedet for at rette i total.
>

For lige at uddybe lidt. Hvis man oversætter følgende metode

public String foo()
{
String result = null;
for (int i = 0; i< 1000; i++) {
char c = 'a';
result += c;
}
return result;
}


så fås

Method java.lang.String foo()
0 aconst_null
1 astore_1
2 iconst_0
3 istore_2
4 goto 32
7 bipush 97
9 istore_3
10 new #5 <Class java.lang.StringBuffer>
13 dup
14 invokespecial #6 <Method java.lang.StringBuffer()>
17 aload_1
18 invokevirtual #7 <Method java.lang.StringBuffer
append(java.lang.String)>
21 iload_3
22 invokevirtual #8 <Method java.lang.StringBuffer append(char)>
25 invokevirtual #9 <Method java.lang.String toString()>
28 astore_1
29 iinc 2 1
32 iload_2
33 sipush 1000
36 if_icmplt 7
39 aload_1
40 areturn

mens

public String bar()
{
StringBuffer result = new StringBuffer();
for (int i = 0; i< 1000; i++) {
char c = 'a';
result.append(c);
}
return result.toString();
}

giver

Method java.lang.String bar()
0 new #5 <Class java.lang.StringBuffer>
3 dup
4 invokespecial #6 <Method java.lang.StringBuffer()>
7 astore_1
8 iconst_0
9 istore_2
10 goto 25
13 bipush 97
15 istore_3
16 aload_1
17 iload_3
18 invokevirtual #8 <Method java.lang.StringBuffer append(char)>
21 pop
22 iinc 2 1
25 iload_2
26 sipush 1000
29 if_icmplt 13
32 aload_1
33 invokevirtual #9 <Method java.lang.String toString()>
36 areturn

Her ses at sidstnævnte kun skaber én instans af StringBuffer.

--
Jonas Kongslund <jonas(at)kongslund.dk> XNS: =Jonas Kongslund

Digital Rights - raising awareness of rights in the digital world
http://www.digitalrights.dk

Martin Ehmsen (06-11-2001)
Kommentar
Fra : Martin Ehmsen


Dato : 06-11-01 00:41

Jonas Kongslund wrote:
<snip: god kode>

Tak for svarene til jer begge. Jeg er aldrig faldet over StringBuffer
endnu, men den er jo helt klart meget anvendelig.
Men det fremhæver også en ting, som jeg synes SUN kunne gøre bedre i
deres dokumentation: Det ville være dejligt, hvis de til hver af deres
metoder angav tidskompleksiteten af den anvendte algoritme...

Mvh.
Martin Ehmsen
--
"Life is good for only two things,
discovering mathematics and teaching mathematics"
Siméon Poisson

Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408527
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste