Kispad

Kispad: közös blog
4230 cikk, 53876 hozzászólás
Szerzők | Tudnivalók | Feedek


Code Review

stsmork cikke a Torokgeek rovatból, 2008. február 11. hétfő, 09:26 | 17 hozzászólás

Felebarátaink kódjának tanulmányozása számos meglepetést tartogat. Itt van például az alábbi kódrészlet:

StringBuffer buf = new StringBuffer();
buf.append("Parameters:\nmode =");
buf.append(mode);
buf.append("\ntype = ");
buf.append(type);
buf.append("\nfile_path = ");
buf.append(file_path);
System.out.println(buf.toString());

Működik ez szépen, de ugyanezt egyetlen sorban is el lehet intézni, sokkal olvashatóbban:

System.out.println("Parameters:\nmode =" + mode + 
                              "\ntype = " + type +
                              "\nfile_path = " + file_path);

Rejtély, hogy a programozó miért használt StringBuffer objektumot, amikor + jelek segítségével jóval egyszerűbben és olvashatóbban érheti el ugyanezt. Az elkövető egyébként évekkel ezelőtt elhagyta a céget, így csak az utódjával tudtam beszélni. Azt mondta, hogy a srác, aki a kódot írta, valahol (talán itt?) azt olvasta, hogy a StringBuffer osztály sokkal hatékonyabb, mint a + jelek használata. Csakugyan így van, de hogy miért akar valaki egy ritkán használt debug utasítást sebességre optimalizálni, azt továbbra se értem. Premature optimization is the root of all evil - mondotta Donald Knuth.

Nem emlékszem már, hogy mit mondtam először, amikor megláttam ezt a StringBufferes kódrészletet, ilyenkor mindenesetre azt szokás mondani, hogy WTF, vagyis What The Fuck. Ez a hárombetűs rövidítés egyébként a kód minőségének mérésére is kiválóan alkalmas, az alábbi illusztráció szerint:

Code Review Metrics

Kép: www.osnews.com

» Ugorj a hozzászóló ablakhoz

Megosztások Facebookon

Eddigi hozzászólások (17)

1

b., 2008. február 11. hétfő, 10:12 (#)

"+ jelek használata"? :D string konkatenálás? egyértelmű, hogy StringBuffer v. StreamBuffer használata javallott minden esetben, minden objektum orientált nyelven. Gondolom nem itt szerepelt először a kódban, refaktoringgal az összes helyen kicserélte korábban (gondolom valami IDE-t csak használ, vagy valami makrót...).
De mindenesetre megmosolyogtató az, hogy magad ismered el, hogy a kód egy kevésbé fontos részén jársz, ahol ezt látod (hozzáteszem egy alkalmazásban minden egyes sor ugyanolyan fontos) - akkor a) miért nem mindegy amit fent látsz; b) miért kellene változtatni, ha a kánon szerint így optimalizált? Fáj, hogy 6 sor az 1 helyett? Ilyet mondott a compiler, h:

WARNING: Too many rows of code found at 2, please rewrite the whole project to be more USER READABLE!!!

ugyan. :)

2

edhellon, 2008. február 11. hétfő, 10:19 (#)

Majdnem bekommenteltem, hogy a "the real WTF" az, hogy nem szabaditja fel a StringBuffer tipusu ojjektumot, aztan rajottem hogy ez Java... bocs, meg nem vagyok tul az elso kvn (az elso meetingen viszont igen, WTF).

Egyebkent nem lehet, hogy hasznaltatok anno valami elbaszott metrikat, ami a commitolt sorok szamabol szamolt valami hatekonysagi mutatot az adott programozora? (Hallottam ilyen esetekrol :)

3

Author Profile Page NagyGa1, 2008. február 11. hétfő, 10:33 (#)

Ez azt hiszem abból adódhat, hogy a String objektum konstans / immutable vagy mi, értéke nem változtatható, ezért a sok sztringmachinációt StringBufferrel szokás csinálni, mert különben a fordító létrehoz vagy ezer Stringet, aztán eldobálja őket.

Csakhogy épp a fenti esetben célszerűbb inkább rábízni a fordítóra, mert ha egy sorban van a sok konkatenáció, akkor bízom benne, hogy jól optimalizálható.

Ha szét lenne tördelve a köd különböző részeire, akkor persze jobb lenne a StringBuffer, már ha fontos a performance, de akkor meg annyival nem is lenne más a kód, mint Stringgel.

Tipikus féltudás esete szvsz. :)

4

viktor, 2008. február 11. hétfő, 11:21 (#)

Egyreszt StringBuilder kene, az nem szinkronizalt, mint a StringBuffer, ha mar teljesitmenyre megyunk. Masreszt, es ez fontosabb, tessek megnezni, hogy a sima + milyen kodot general: egy jo ideje a StringBuilder forditja be a javac a konkatenalas helyere. Konkluzio: ne optimalizalj (itt) kezzel.

5

Author Profile Page PAStheLoD, 2008. február 11. hétfő, 13:08 (#)

Hogyhogy még senki nem említette, hogy "WTF? Java?"? :)

6

tegla, 2008. február 11. hétfő, 14:02 (#)

A fölösleges String-allokáció meg nem lassít semmit.

Egy modern Java JIT a sztring-összeadásos példából olyan kódot készít, ami nem allokál semmit a heap-en, és nem is szinkronizál sehova.

7

pro, 2008. február 11. hétfő, 14:37 (#)

Márpedig ha nem a performance, akkor a user-readability a legfontosabb.

8

tallian.miklos, 2008. február 11. hétfő, 18:16 (#)

(Csendben mondom, van olyan, egyébként kiváló program, ami az összes változót valamilyen szeszesitalról nevezi el magában. Ez nagyon jól javítja az olvashatóságot.)

9

pblue, 2008. február 11. hétfő, 18:16 (#)

vilagos, hogy kellett egy apropo az amugy tenyleg vicces wtfs/minute abrahoz, de akkor se ertem, hogy merpont ilyen. ez miert ennyire erdekes?

viszont ha mar wtf es kodolas: http://thedailywtf.com

10

karaj, 2008. február 11. hétfő, 19:17 (#)

Code review... a legszebb az volt eddig, mikor találtunk egy osztályt (c++), ami megvalósított egy 16 bites bitmap tárolást, ehhez bevezetett két int membert (az alsó és a felső byte-hoz), aztán csinált 32 darab tagfüggvényt, hogy get1stbit(), set1stbit(), get2ndbit(), set2ndbit()... stb. ezekben pedig osztás-szorzással kisilabizálta az aktuális bit értékét a két intből, és visszadta int-ben, hogy 0 vagy 1, illetve set-nél fordítva. Én ennél szebbet még az életben nem láttam, még a könnyem is csorgott a röhögéstől, mikor megtaláltuk.

11

gargoyle, 2008. február 12. kedd, 01:25 (#)

azert ezek a kommentek igy kivulallokent ijesztoek. maskepp fogalmazok
_i_jesz_to_ek

(:

de en beilleszkedem barhova, ezeken is nevettem, de tenyleg :D

12

wice, 2008. február 12. kedd, 08:26 (#)

damn! jol lemaradtam, pedig en is elmeselhettem volna, h a stringbuffer szinkronizalt, es, h a fordito ugyanugy forditja a +-os kifejezest. stringbuffert es stringbuildert csak akkor erdemes hasznalni, ha ciklusban generalod a stringet.

monnyuk nemtom, mikor irta ezt a kodot, mert regebben, a java akarhanyban meg valoban gyorsitott, ha joltom. (btw, system outtal debuggolni... eh-eh...)

viszont ami viccesebb, nekem kb egy eve volt olyan munkam, ahol a megrendelo kotelezove tette, h stringbuffert hasznaljunk _minden_ stringkonkatenacional, "meraz gyorsabb". engem meg rohadtul idegesitett, ugyhogy rakerestem, h telleg van-e ertelme, akkor derult ki, h semmi. nehez volt megertetni veluk :)

13

pblue, 2008. február 12. kedd, 12:43 (#)

btw akkor mar megkerdezem toletek is: szerintetek melyik a gyorsabb konverzio, a

String.valueOf(x)

vagy a

"" + x

(ahol x egy integer mondjuk)

14

Author Profile Page NagyGa1, 2008. február 13. szerda, 02:02 (#)

Meg kell nézni mit fordít oda a fordító. (pl jad-dal, azt hiszem van egy ilyen nevű Java disassembler)

15

Author Profile Page NagyGa1, 2008. február 13. szerda, 02:17 (#)

Khmmm...

Szerintem az első elvileg gyorsabb, a disassemlált forrás így néz ki:

// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3)
// Source File Name: MikTest.java


public class MikTest
{

public MikTest()
{
}

public String test(int i)
{
String s = String.valueOf(i);
return s;
}

public String test2(int i)
{
/** Ez volt az "" + x eredetileg */
String s = (new StringBuilder()).append("").append(i).toString();
return s;
}
}

Persze ettől még lehet, hogy mégsem, ki tudja mit csinál az interpreter. Mindenesetre a CheckStyle is az elsőt ajánlja ha jól emlékszem.

16

pblue, 2008. február 13. szerda, 12:08 (#)

igende a checkstyle az nem tobb mint pain in the ass :)

17

Author Profile Page NagyGa1, 2008. február 13. szerda, 13:07 (#)

Vagy csak NSDAP tagsági vizsga... :)


Hozzászólsz?

Igen

Hozzászólást csak névvel együtt fogadunk el. Ha linket írsz be, akkor előtte és utána hagyj egy szóközt, főleg akkor, ha zárójelbe teszed.


Az oldal tetejére | Szerzők, tudnivalók, feedek | sesblog és Kispad © 2003-2010 ervin, eszpee, stsmork