Diskuze: Pomoc s programem
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 28 zpráv z 28.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
Tak jedna chyba je ve druhém cyklu - nemělo by tam být "j < seznam.Size()" místo "i < seznam.Size()"?
Kvůli tomuto:
for (int j = 0; i < seznam.size(); j++) {
Mimochodem hodilo by se tam přidat toto:
pocetVyskytu=0;
Tak ještě bych potřeboval poradit. Spustil sem debug file a pokaždé mi to vypisuje u proměnné pocetVyskytu 1. Nevíš v čem by mohla být ještě chyba?
Môžeš to zjednodušiť tak, že miesto for cyklu použiješ foreach cyklus.
Ahoj, nejsem si jist, jak je to u javy ale typl bych, že je to tím, že přidáváš do slovníku celé věty a né slova
String radek = br.readLine();
seznamSlov.add(radek);
viz tyto řádky, myslím že nejdříve musíš řádek rozdělit do slov..
Jako myslíš místo toho vnořeného for cyklu? Nebo teď to moc nechápu.
for (int i = 0; i < seznam.size(); i++) == foreach i in seznam
ale je to drobnost, používet to, co ti víc sedne
Foreach cyklus je upravený for cyklus ktorý sám prejde prvky v poli. Takže miesto
for (int i = 0; i < seznam.size(); i++) {
porovnavaneSlovo = seznam.get(i);
}
máš
for (String porovnavaneSlovo:seznam) {
}
Doplním, že foreach je o niečo rýchlejší ako klasický for a na to aby sa dal použiť foreach, musí daná kolekcia implementovať interface Enumerable, ak si správne pamätám. Používa sa keď potrebuješ iba hodnoty prvkov a nepotrebuješ meniť pôvodné hodnoty v poli/kolekcii
No, niekde som čítal že foreach je pomalší ,ale to je úplne zanedbateľne v porovnaní s tým že je to potom prehľadnejšie . A asi si myslel interface Enumeration, ale to sa použiť iba na klasický for (https://docs.oracle.com/…eration.html). Na to aby sa dal použiť foreach sa musí implementovať interface Iterable.
Panove, foreach neni ani rychlejsi a ani neni zanedbatelne pomalejsi... nikdy bych ho nedpoporucil pouzivat v zadnem jazyce na zadne platforme, pokud nejste dohnani jedinou moznou vyjimkou k tomuto nouzovemu reseni ( a to kuprikladu faktem, ze proste nejste schopni zjistit kolik jednotek v kolekci bude... treba pokud se nejak nerozumne meni pocet prvku v kolekci) ... jestli chcete delat programy co budou za neco stat musite myslet na rezii... nejde si jen tak rict ze milisekunda tam milisekunda sem to nikoho neboli... tenhle pristup nejde praktikovat.. jinak samozrejme no-offense
Pokud vím, tak foreach se zkompiluje na for, takže vaše diskuze je zcela
zbytečná.
Názor nepoužívat foreach je taktéž zcestný, protože výrazně zlepšuje
přehlednost kódu (ve většině případů), proto ho také máme. Nemyslím
si, že by inženýři navrhující většinu programovacích jazyků přidali
nějaké zbytečné zpomalovátko, to nedává smysl
Foreach je trošku rýchlejší, lebo počíta veľkosť pola iba raz (čo sa dá samozrejme dosiahnuť aj pri for cykle ofc), a mne teda príde častokrát omnoho lepšie čitateľný ako klasický for + pri foreachi je záruka, že nikde v tom cykle sa nemenia hodnoty tej danej kolekcie
Zasadni je podle me myslenka, ze inzenyri co navrhli cecko nenevrhovali
javu...
Ja budu uplne spokojenej kdyz si tenhle kod spustite na vasich masinach a
parkrat se kouknete na vystup..rekneme desetkrat...dvacetkrat ...
padesatkrat... tak jako jsem to udelal ja...
bezi to vzdy jen jednou, protoze JVM ma celkem slusne vymyslenou optimalizaci za
behu...prece jenom nejsou to zadni sumari lidi co to delaj... rekneme ze bezne
male pole, i s interakci s prvkem dostatecne demonstruje co je rychlejsi a o
kolik... jestli mi nekdo z tech, co se mnou nesouhlasi nebo Jakub, ktery mi jen
dal minus a nevyjadril se vysvetli proc tomu tak je a ukaze se, ze jsem se
zmylil rad si znovu prostuduju materialy a projdu dokumentaci na netu.
public static void main(String[] args) {
long time1;
long time2;
long time3;
long time4;
int[] experArr = new int[100000000];
for (int i = 0; i < experArr.length; i++) {
experArr[i] = i;
}
time3 = System.nanoTime();
for (int item : experArr) {
//System.out.println(item);
}
time4 = System.nanoTime();
time1 = System.nanoTime();
for (int e = 0; e < experArr.length; e++) {
//System.out.println(pole[i]);
}
time2 = System.nanoTime();
System.out.println("for: " + (time2 - time1));
System.out.println("foreach: " + (time4 - time3));
if ((time2 - time1) < (time4 - time3)) {
System.out.println("for je rychlejsi presne o: " + ((time4 - time3) - (time2 - time1)) + " nanosekund");
}
if ((time2 - time1) > (time4 - time3)) {
System.out.println("foreach je rychlejsi presne o: " + ((time2 - time1) - (time4 - time3)) + " nanosekund");
}
}
Co třeba tohle: http://stackoverflow.com/…-an-iterator
Ja presne nevim co na tomhle miste rict... ano typek to na SO popsal moc hezky... fakt bych tomu i veril, kdyby ovsem test neukazal neco jineho... na deset pokusu pripada asi 8 - 9 kdy je for rychlejsi o radove 10−7 sekundy ... idk ... neni to moc dulezity tak to necham byt ...
Mínus jsem ti dal za "doporučení" nepoužívat foreach, protože prostě postrádá logiku.
Foreach je hlavně o srozumitelnějším a přehlednějším zápisu, což je obecně důležitější. Ještě jsem nikdy neslyšel, že by ho někdo nedoporučoval, spíš naopak.
Pokud by někomu šlo výkon, tak by jistě nasadil JIT, který prý umí foreach lépe optimalizovat. Myslím, že jsem to slyšel zde: http://java.cz/…ava-aplikaci
Navíc je ten tvůj testovací kód špatně, fori totiž nepřistupuje k prvkům pole, zatímco foreach ano.
Miluju tyhle dětské benchmarky i to, jak se v nich dá podvádět.
Vzal jsem tvůj kód a trochu ho upravil do rigoróznější podoby.
Výsledek (hodnota je, kolik se stihlo udělat cyklů v časovém rozmezí):
$ java -version
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
$ java test
for: 20 < foreach: 21
for: 42 < foreach: 199
for: 20 > foreach: 19
for: 51 < foreach: 203
for: 21 < foreach: 21
for: 202 < foreach: 202
for: 6 < foreach: 21
for: 50 < foreach: 201
for: 21 < foreach: 21
for: 197 < foreach: 204
for: 6 < foreach: 20
for: 51 < foreach: 201
for: 20 < foreach: 21
for: 200 > foreach: 199
for: 5 < foreach: 20
Můj kód pro replikaci výsledků:
public class test
{
public static void main(String[] args) {
int[] experArr = new int[100000000];
for (int i = 0; i < experArr.length; i++) {
experArr[i] = i;
}
while(true) {
iterate(1000000000L, experArr);
iterate(10000000000L, experArr);
iterate2(1000000000L, experArr);
iterate2(10000000000L, experArr);
}
}
private static void iterate(long K, int[] list) {
long time1;
long time2;
long time3;
long time4;
int cycles1 = 0;
int sum1 = 0;
time3 = System.nanoTime();
do {
for (int item : list) {
sum1 += item;
}
cycles1++;
time4 = System.nanoTime();
}
while (time4 - time3 < K);
int cycles2 = 0;
int sum2 = 0;
time1 = System.nanoTime();
do {
for (int e = 0; e < list.length; e++) {
sum2 += list[e];
}
cycles2++;
time2 = System.nanoTime();
}
while (time2 - time1 < K);
System.out.print("for: " + cycles2);
System.out.print(cycles1 >= cycles2 ? " < " : " > ");
System.out.println("foreach: " + cycles1);
}
private static void iterate2(long K, int[] list) {
long time1;
long time2;
long time3;
long time4;
int cycles1 = 0;
int sum1 = 0;
time3 = System.nanoTime();
do {
for (int item : list) {
sum1 += item;
}
cycles1++;
time4 = System.nanoTime();
}
while (time4 - time3 < K);
int cycles2 = 0;
int sum2 = 0;
time1 = System.nanoTime();
do {
for (int e = 0; e < list.length; e++) {
sum2 += list[e];
}
cycles2++;
time2 = System.nanoTime();
}
while (time2 - time1 < K);
System.out.print("for: " + cycles2);
System.out.print(cycles1 >= cycles2 ? " < " : " > ");
System.out.println("foreach: " + cycles1);
}
}
Zaujímavé, takže foreach je v priemere rýchlejšie ako for.
Pozrel som si tvoj kód trochu podrobnejšie, ale foreach tam vôbec netestuješ, alebo mi niečo ušlo?
To netvrdím, jen umím napsat benchmark, kterým to jde dokázat.
Stejně tak můžu napsat benchmark, který dokáže opak - proto tomu říkám
"dětské" benchmarky.
Rychlejší (v Javě) je v situacích, o kterých se píše na SO (odkaz
výše), ale s tím tyhle benchmarky vůbec nesouvisí.
Naproti tomu v Objective-C jsou fast enumeratory rychlejší než indexované
cykly, ale důvod je za hranicí toho, abych to mohl vysvětlit.
Jak vidim, nemel jsem uplne pravdu ... pripoustim, ze moje nevrazivost vuci foreach je na tomhle miste opravdu zbytecna, sveho casu jsem u starsi verze javy cetl, ze je pomalejsi a informaci jsem si ponechal doted... beru to zpet... koneckoncu chybama se clovek uci... takze diky za vase informace, cenim si vaseho vstricneho (a do znacne miry i pratelskeho) pristupu
V době, kdy to ten člověk psal, byla pomalá celá java a dotyčný zřejmě nedokázal docenit výhody for-each zápisu.
Tys udělal jedinou chybu, a tou bylo, že jsi nezužitkoval výsledky svého
testu.
Můžeš si to zkusit, jak se to dělá doopravdy:
Tam uvidíš relativní hodnoty a dozvíš se, kolik sekund ušetříš při
hodinovém běhu.
Když pak porovnáš rozdíly časů, dozvíš se například, že zisk v praxi
je 0.5 sekundy na 1 hodinu.
Zlaté pravidlo zní, pokud potřebuješ hodnoty indexů, tak for-cyklus, jinak vždy for-each.
Myslim, ze chapu .... a nakonec jsem docela rad, ze jsem se do te diskuze pustil, tenhle poznatek rozhodne zuzitkuju ... dik
Zobrazeno 28 zpráv z 28.