Kai kurie programavimo aspektai (Java, C)
Ar K=K+1; K++; ++K; daro tą patį?Tiek C (C++), Java ir kitose panašiose kalbose K=K+1; K++; ++K; rezultatas yra tas pats, tad gali kilti įsitikinimas, kad jos sukeičiamos.
Tačiau buvo klausta kitaip: ne koks jų rezultatas, o kaip jos atliekamos. Ir čia jos nežymiai skiriasi. Štai kaip jos vykdomos išraiškose:
K++ padidina K reikšmę, tačiau gražina ankstesnę K reikšmę; ++K padidina K reikšmę ir gražina naują K reikšmę (po priskyrimo); K=K+1 prie K prideda reikšmę ir gražina tą paskaičiuotą K reikšmę (po priskyrimo; t.y. kaip ++K). Tasai po priskyrimo yra šiek tiek įdomus. ++K ir K=K+1 gali sutrimpinti reikšmę. Tarkim, paimkim to kį bjaurų kodą:
public class TestPPByte { public static void main(String[] args) { byte b = (byte)0xFF, b42 = (byte)0x42; System.out.println("B=" +HEX(b) + "; b42=" + HEX(b42)); byte m1 = MIN(++b, b42); b = (byte)0xFF; byte m2 = MIN(b=(byte)(b+(byte)1), b42); b = (byte)0xFF; byte m3 = MIN(b++, b42); System.out.println("Min1=" + HEX(m1)); System.out.println("Min2=" + HEX(m2)); System.out.println("Min3=" + HEX(m3)); } private static byte MIN(byte p1, byte p2) { return (p1<p2)? p1 : p2; } private static String HEX (byte p) { return String.format("%02X", p); } }Jis pateiks tokį atsakymą:
B=FF; b42=42 Min1=00 Min2=00 Min3=FFKodėl yra taip, suprasime, jei pažiūrėsime, kaip paskaičiuojamas minimumas pirmu ir trečiu atvejais:
m1 = MIN(++b, b42) - ++b paskaičiuoja naują b reikšmę (0xFF+1=00) ir ją (00) perduoda funkcijai;
m3 = MIN(b++, b42) - b++ paskaičiuoja naują b reikšmę (0xFF+1=00), tačiau funkcijai perduoda ankstesnę reikšmę (0xFF).Tiesa, praktikoje visi tie atvejai praktikoje mažai skiriasi. Tiesiog reikia naudoti tai, kas skaitomiausia jums arba sekite kodavimo patarimais.
Iš kur Javos tas lėtumas?
Pastaba: Šis straipsniukas buvo paskelbtas 1998 m. Nuo to laiko daug kas pasikeitė, tačiau jis paliktas kaip istorinis reliktas, parodantis to laikmečio aktualius klausimus.
Programinė įranga visad tik lėtėja, o ne greitėja. Dabartinės teksto tvarkymo programos ant "Pentiumų" sukasi ne greičiau (o kartais ir lėčiau) nei jų senieji protėviai XT kompiuteriuose, kuriuos daugelis naujosios kartos atstovų ko gero gali išvysti tik muziejuje.
Kasdien prisiklausome daug įvairių vertinimų. Vienas jų - kad "Java" kalba yra lėta kaip vėžlys lyginant su kitomis, pvz., C/C++. Ar ji ir toliau pasmerkta likti tokiu lėtapėdžiu? Manoma visaip, tačiau nemažai secialistų nesutinka su tokia pesimistine nuomone. Jie mato net devynis būdus leidžiančius pagreitinti "Java" programų greitaeigiškumą. Juk "Java" programų vykdymo greitis - pagrindinis veiksnys ne tik jos pergalei, bet ir išlikimui.
Jau dabar "Java" naudojama nemažai sričių, kuriose pakanka jos greičio. Daugiausia tai centralizuotos programos, kurios veikia galinguose serveriuose. Tačiau kitur ji kenčia nuo tų pačių bėdų, kaip ir jos pirmtakai - objektiškai orientuotos kalbos, pvz., "Smalltalk". Net populiariusis "Visual Basic" ne visda priimtinas dėl lėtesnio greičio lyginant su C++. Tad kas gali pagreitinti "Java" ir gelbėtijos prestižą?
ABSOLIUČIAI NEREIKALINGI FAKTAI
- Vienintelis naminis gyvūnas neminimas Biblijoje yra katė;
- Stalo teniso kamuoliukai gali skristi net iki 160 km/h;
- Į "Pepsikolos" gėrimą anksčiau būdavo dedama pepsino. Iš to kilo šio gėrimo pavadinimas;
- Tikroji "Tūkstantis ir viena naktis" istorija prasideda taip: "Aladinas buvo mažas kiniečių berniukas...";
- Suleistas į veną muskatas būtų labai nuodingas;
- Medus yra vienintelis natūralus produktas, gaminamas nesunaikinant jokios gyvybės; O kaip su pienu? - paklausite jūs. Tam, kad pagamintų pieno, karvė turi ėsti žolę, o žolė yra gyva;
- Vienas Maiklas Džordanas iš NIKE per metus uždirba daugiau pinigų nei visi Nike gamyklos darbuotojai Malaizijoje kartu sudėjus.
- Geresni "Java" kalbos kompiliatoriai, kurie kompiliuoja "Java" kalba parašytas programas (.java failus) į "universalų" "bytecode" (.class failus) formatą, kurį moka priimti visos virtualos "Java" mašinos (JVM).
- Greitesnės JVM, kurios yra tarpsluoksnis tarp, pvz., WWW naršyklės ir operacinės sistemos. Jos ne tik interpretuota "bytecode" failus, bet ir atlieka daugelį kitų darbų, pvz., surenka atminties "šiukšles".
- "Bytecode" formato optimizatoriai - programos, kurios pertvarko kitų kompiliatorių paruoštą "bytecode".
- Kompiliatoriai "įkėlimo" metu (JIT) - JVM komponentai, kurie .class failo įkėlimo metu "bytecode" transliuoja į konkrečios (o ne abstrakčios, kaip "bytecode" atveju) mašininius kodus ir "kešuoja" sutransliuotą programą operatyviojoje atmintyje. Tokia sutransliuota į mašininius kodus programa vykdoma daug sparčiau, o JIT turi dauguma WWW naršyklių.
- Dinaminiai (prisitaikantys) kompiliatoriai, kurie "bytecode" transliuoja į mašininius kodus "Java" programos vykdymo metu - t.y. atsižvelgia į programos vykdymo specifiką. Tokio pagreitinimo pavyzdys yra "Sun" firmos sukurta "HotSpot" technologija.
- Kompiliatoriai į mašininius kodus. Šie kompiliatoriai "Java" programas arba "bytecode" sutransliuoja (ir užrašo į diską) į mašininius kodus (kuriuos kaip failą užrašo į diską) - panašiai, kaip tai daro C/C++ ir kitų įprastinių kalbų kompiliatoriai.
- Mašininiu kodu parašytų metodų (paprogramių ar DLL parašytų, pvz., C++ kalba) iškvietimas iš "Java" programų.
- "Java" mikroschemos. Tai specialūs mikroprocesoriai, kurių mašininis kodas sutampa su "bytecode" - nėra reikalo jo transliuoti į kitą mašininę kalbą.
- Geresnės kokybės programų rašymas. Paskutinėje vietoje - bet ne mažiau svarbus! Programuotojai turi įsisąmoninti, kad programavimo kokybė gali būti lemiamas veiksnys.
O kad geriau suprastume, kodėl šie būdai gali pagreitinti "Java" programų vykdymą, prieš tai turime gerai suprasti, o kodėl "Java" programos yra lėtos. Pagrindinė priežastis - "Java" yra dinamiškai "surenkama" objektiškai orientuota programavimo kalba. "Java" programų klasės "nesurišamos" iki pat programos vykdymo laiko - tik tuo metu galima išspręsti polimorfinius kreipinius į paprogrames savo objektų hierarchinėje struktūroje. Kai "vaiko" klasėje metodas (paprogramė) perdengia "tėvo" klasės metodą, tą perdengimą galima nustatyti tik vykdant programą (prioritetai gali pasikeisti, jei programa įkels kitą klasę).
C kalbos kompiliatoriai veikia kitaip - jie jau kompiliavimo (link) metu suriša programą su visomis jos paprogramėmis - to nereikia daryti programos vykdymo metu. Bet C++ turi galimybes "vėlyvajam" surišimui ir polimorfinėms (panašioms į "Java" metodus) operacijoms - ir todėl taip pat kenčia nuo objektų hierarchijos. Todėl ir C++ programos yra šiek tiek lėtesnės už C programas.
Kitas programų sulėtėjimo šaltinis - iki tol neregėta galimybė vykdyti tas pačias "Java" programas įvairiose platformose, t.y., didelis aparatūrinės abstrakcijos lygis. Jis buvo programuotojų svajonė pradedant pirmasiais kompiuteriais. Kelias ėjo pradedant "kietai" užkoduotu ENIAC kodu per asemblerį, programavimo kalbas OS API iki objektų bibliotekų. Kiekviename lygyje reikėjo vis mažiau žinių apie aparatūrą, bet vis daugiau laiko reikėjo programos vykdymui. Laimė, procesorių pajėgumai irgi greitai augo.
Kaltės jausmas
Dažnų firmų darbuotojai gauna dešimtimis ir daugiau laiškų per dieną. O kur dar faksai, telefonų skambučiai, lipdukai su žinutėmis, mobilūs telefonai ir t.t. Dėl šio informacijos Tvano, jie priversti per valandą nutraukti savo veiklą po kelis kartus ir nuolat keisti savo tvarkaraštį ir darbų prioritetus. Su bendradarbiais palaikomas ryšys net tada, kai jie ne įstaigoje.
Gal tuščia pašto dėžutė būtų labiausiai geidžiamas tikslas? Kai mes neatsakome į kokius nors laiškus, jaučiame kaltės jausmą, kad sugriovėme įprastinę tvarką ir toje sistemoje esame "silpna grandis". Tokia neatsakinėjimo į laiškus praktika gali tik padidinti nerimą, sutrikdyti bendravimą ir netgi padidinti susirūpinusių skambučių ir el.laiškų srautą.
Todėl beveik aišku, kad įvairių pranešimų tvarkymo įrankių tik gausės. Tačiau poreikis "gyvai" bendrauti irgi neišblės...
Su "Java" atsirado ir JVM, tai programinė abstraktaus procesoriaus imitacija, kuri vykdo abstrakčiai mašinai paruoštą mašininį kodą ("bytecode"). Tad ji turi atlikti papildomus veiksmus versdama tą abstraktų mašininį kodą konkretaus procesoriaus komandomis. O tai jau greičio praradimai - tuo labiau, kad programuotojai rašydami programas neatsižvelgia į jokią konkrečią aparatūrą.
Bet ir to nepakanka! JVM nuo programuotojo paslepia ir kitus dalykus, kuriuos ji pati apsiima tvarkyti, pvz., automatizuodamą atminties valdymą. C/C++ kalbose programuotojas turi pats savo programose tvarkyti atminties išskyrimą ir sugrąžinimą. O netvarkingas darbas su atmintimi yra viena iš pagrindinių C programų nestabilumo priežasčių. "Java" pašalina šios rūšies (o taip pat masyvo rėžių tikrinimo, bei "nulinių" nuorodų ar dalybos iš nulio ir t.t.) galvos skausmą, tačiau papildomų veiksmų (taigi ir greičio praradimo) kaina (atminties valdymas užima nuo 15 iki 25% JVM veiklos).
JVM tik pusę laiko praleidžia tiesiogiai vykdydama "Java" programą - likusį laiką užsiima įvairiais kitais darbais. Tačiau jos nuolat greitėja: lyginant su pirmosiomis jų greitis jau padidėjo (pasirodžius JDK 1.1) daugiau nei 2 kartus. Tai atsitiko iš dalies atsisakant pranešimų apie įvykius (pelės judėjimą,. klavišų paspaudimą ir t.t.) siuntimą visiems objektams. Dabar tuos pranešimus gauna tik registruoti "klausytojai" - tad kitiems objektams nereikia gaišti laiko tikrinant tuos pranešimus.
Kiekvienas privalumas turi ir savų trūkumų. "Java" turi labai galingą lygiagrečių procesų valdymo galimybę, o konfliktai tarp jų sprendžiami "sinchronizuojant" metodą (t.y. nurodant, kad tik viena programos gija vienu metu gali vykdyti kurį nors "Java" metodą). Tačiau sinchronizuoti metodai ("paprogramės") vykdomos lėčiau ("Sun" firmos "HotJava" naršyklės JVM lygiagrečių gijų valdymui sugaišta net iki 25% savo darbo laiko).
O pagaliau - "Java" nors ir ribotas, bet efektyvus saugumo mechanizmas, draudžiantis "apletams" skaityti ir rašyti į lokalaus kompiuterio diskus, kitų programų (ne iš serverio) iškvietimą ir t.t.
Tad trumpai peržvelgėme "Java" lėtumo priežastis, išvardinome galimus tos stichinės nelaimės pašalinimo būdus, O ką "geležiai" gali padėti programuotojas - paieškokite "Vartiklyje".
Tcl kalba
Tiesiog - Java
Minties virusai
Unix komandinės eilutė
Java 8: Optional prieš null
Lambda išraiškos: Java į naują lygį
Kas ten skrieja prie degančios žvakės?
Toji pirmoji naktis arba Failas 'X', Nr.3
Mitas apie kompiuterių revoliuciją
Istorijos ratas: pasikartojimai?
Pasakykite tai mano avatarui
Ką Internetas davė Elizai?
Nematomo žmogaus kultūra
Niekada nesakyk, kad mirė
Kompiuteris rodo dėmesį
Surask geriausią!
Tylos kalba
Vartiklis