Kartais tenka realizuoti veiksmo parinkimą priklausomai nuo atėjusiojo kintamojo reikšmės. Daugelis programavimo kalbų tokiai situacijai gali pasiūlyti dvi technologijas: if else arba switch case.
Užduotis: gautą skaičių paversti žodžio atitikmeniu. Galbūt nelabai praktiška užduotis, bet dar labiau nepraktiškos užduoties sugalvoti nepavyko. Užduoties realizacijai pasirinkau PHP programavimo kalbą (nors kaip minėjau anksčiau, daugelis programavimo kalbų turi tokias struktūras), kadangi PHP yra interpretuojama kalba, nereikia nieko kompiliuoti, tiesiog parašiai ir iškarto matai rezultatus.
Pirmiausia parašykime tokį kodą su if else
(Pastaba: susilaukęs daug kritikos dėl lietuviškų kintamųjų pavadinimų, nusprendžiau neapsimetinėti kuo neesu ir kintamieji nuo šiol bus angliški)
if($number==0) $word="nulis"; else if($number==1) $word="vienas"; else if($number==2) $word="du"; else if($number==3) $word="trys"; else if($number==4) $word="keturi"; else if($number==5) $word="penki"; else if($number==6) $word="sesi"; else if($number==7) $word="septyni"; else if($number==8) $word="astuoni"; else if($number==9) $word="devyni";
Kodas manau daugiau negu aiškus, patikrinam ar tinkamas kintamasis, jei ne pereiname prie kitos sąlygos. Idomu, kad PHP kalboje vietoj else if galime tiesiog rašyti elseif.
Dabar perrašykime tą patį kodą su switch case operatoriais
switch ($number) { case 0: $word="nulis"; break; case 1: $word="vienas"; break; case 2: $word="du"; break; case 3: $word="trys"; break; case 4: $word="keturi"; break; case 5: $word="penki"; break; case 6: $word="sesi"; break; case 7: $word="septyni"; break; case 8: $word="astuoni"; break; case 9: $word="devyni"; break; }
Jeigu palygintumėte su ankstesniu kodu, tai pastebėtumėte, kad case 0: atitinka if($number==0) ir t.t. Taip pat svarbu nepamiršti funkcijos break;, nes, jeigu ta funkcija bus praleista, tai bus peršokta nuo vienos case sąlygos iki kitos, kol bus rasta bent viena su break; , aišku kartais tai naudinga. Taip pat reikėtų paminėti dar vieną galimą variantą default:. Tokią sąlygą galima užrašyti ir ji bus tenkinama, kai netenkis visų kitų.
Dabar pats svarbiausias klausimas, kas geriau? Pagrindiniai du kriterijai: pirmas - kodo skaitomumas/suprantamumas, antrasis - veikimo greitis. Dėl pirmojo leisiu spręsti jums ir iš karto pereisiu prie antrojo punkto. Kaip išsiaiškinti kuris iš jų greitesnis?
Aukščiau pateiktus kodus apvilksime sekančiu
for($i=0; $i<1000000; $i++){ $number=rand(0,9); //cia kodas }
Tai reiškia, kad scriptas atsitiktinai parinks reikšmę ir bus vykdomas milijoną kartų. Be abejonės, dar reiktų matuoti vykdymo laiką, kaip matuojamas laikas aš jau pasakojau anksčiau
Taigi turim viską, pradedam testuoti
if else
1) 3.81370401382
2) 3.7397711277
3) 3.77952718735
switch case
1) 3.19686388969
2) 3.22155189514
3) 3.24016785622
Ką gi rezultatai kalba patys už save, nors busiu atviras, jie mane tikrai nustebino. (Įdomu, kokių rezultatų sulauktume kitose programavimo kalbose?)
Nuorodos
else
esleif
switch
break
rand
2006-08-29 | 9:00
Python’e switch statement’o nėra :)
Tačiau galima padaryti tą patį ką su switch statement’u kitose kalbose (ir atskirais atvejais daugiau negu kitose kalbose, pvz.: C, dėl PHP nežinau). Ir veiks greičiau.
Ir apskritai nepaslėpta nuo programuotojo ką reiškia switch statement’as ir kodėl jis veikia greičiau atskirais atvejais :)
Geros dienos.
2006-08-29 | 9:16
Nepo, tu esi is kosmoso :|
2006-08-29 | 9:23
o tu gal netycia ir reals.lt programavai? :))))
2006-08-29 | 9:28
Padariau tavo testa su Zend Profiler, rezultatai nera jau tokie skirtingi, kaip pas tau:
IF:
4306.55ms
4284.57ms
4317.34ms
IF (nudojant skliaustus { }):
4530.49ms
4439.42ms
4443.49ms
SWITCH:
4273.72ms
4339.71ms
4267.95ms
Bendrai, štai toks paliginimas (kur visas akcentas sudėtas ant laiko) nieko nesako apie IF/ELSIF ir SWITCH nauojimo tam tikrais atvejais privalumus. Aš manau kad jie kitur, o butent, tuose strukturuose, kurios įmanoma realizuoti su SWITCH, tu juos monėjai ;-)
P.S.: Užduotis: “gautą skaičių paversti žodžio atitikmeniu” atlikčiau masyvų pagalba: http://p.pixel.lt/paste/1255ece77253ec27a9a9a77b133d3a82
P.P.S.: Taip, aš puikiai žinau, kad kritikuoti lengviau, nei rašiti straipsnius.
2006-08-29 | 9:28
va C#
if/else statement
00:00:00.1631250
00:00:00.1562500
00:00:00.1562500
00:00:00.1562500
00:00:00.1562500
case statement
00:00:00.1562500
00:00:00.1406250
00:00:00.1406250
00:00:00.1562500
00:00:00.1406250
o siaip istikruju nelabai cia tikslinga matuoti performanca ant tokiu daliku :)
2006-08-29 | 9:48
Busiu atviras, tu NePo mane kaskart vis labiau stebini :|
2006-08-29 | 18:07
$words = array(”nulis”, “vienas”, …);
$word = $words[$number];
// cia galim prirasyt
// dar dafiga komentaru
// kad skriptas neatrodytu juokingai
// paprastas - is dvieju eiluciu? :)
// ir juokingai lengvai skaitomas
// medutis :|
2006-08-29 | 18:13
ZaZa, o masyvais kiek laiko užtrunka?
2006-08-30 | 8:29
Štai toks variantas: http://p.pixel.lt/paste/1255ece77253ec27a9a9a77b133d3a82
2839.98ms
2836.65ms
2862.95ms
Įspudingas greitis ;-)
2006-08-30 | 14:43
medutis butent! :-D pirstu i aki. NePo what the hack :|
2006-08-30 | 16:52
Slave-4-Code, esmė buvo parodyti if else ir switch veikimo principus ir padaryti išvadas kas greičiau veikia, o ne kaip optimaliai padaryti užduotį jog pagal skaičių priskiriam žodį. Paprasčiausiai buvo pasirinktas toks uždavinys ir tiek. Praktiškai bet kokias užduotis galima išspręsti įvairiais būdais.
2006-08-31 | 9:27
“if else” ir “switch” veikimo principus parodėte paviršutiniškai.
Kitu “nepriklausomu” tyreju duomenis parodo visai kitoki rezultata.
Šeip, klausimas: kokia prasmė lyginti 2 kalbos strukturas, skirtos viena kita papildyti, o nepakeisti?
2006-09-18 | 0:07
cia hashu prasosi. ne kokiu nors masyvu ar dar kazko. Elementariausiu hashu.(kitose kalbose vadinamu asociatyviniais masyvais). O(1) paieskos laikas.
2006-09-30 | 10:09
Reikėjo paminėti, kad kartais switch’as gali būti realizuojamas ‘jump table’ (compiler level), ypač, jei reiškmės yra mažai išsibarsčiusios. Bet kuriuo atveju tokios strukturos niekada nestabdo ;)
2006-10-31 | 11:00
geras!
2006-12-05 | 7:49
[…] Vienas žmogus iškėlė klausimą, kuris ciklas while ar for sukasi greičiau, kadangi aš jau rašiau if else vs. switch case, tai negalėjau neatsakyti į šį klausimą. […]