07. april 2003 - 23:55Der er
28 kommentarer og 1 løsning
Check af indhold i en streng
Jeg sidder med en String-variabel som jeg meget gerne vil checke for at se om den udelukkende indeholder tal (det skal den meget gerne i det givne tilfælde). Hvordan får jeg mit program til at gøre det?
nej det er det ikke, for tror man der kan komme andet end tal, checker man det før.
try/catch løsningen er forresten langsommere, resultat: test 1 (try/catch) = 140 test 2 (hjemmelavet)= 20 test 3 (isDigit() ) = 50
/** * Created by IntelliJ IDEA. * User: Søren Reinke * Date: Apr 8, 2003 * Time: 12:21:38 AM * To change this template use Options | File Templates. */ public class Benchmark { private static final int antal=10000;
private static final String text="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890a";
public Benchmark() { long start1=System.currentTimeMillis(); for(int x=0;x<antal;x++) { test1(text); } long stop1=System.currentTimeMillis(); long start2=System.currentTimeMillis(); for(int x=0;x<antal;x++) { test2(text); } long stop2=System.currentTimeMillis(); long start3=System.currentTimeMillis(); for(int x=0;x<antal;x++) { test3(text); } long stop3=System.currentTimeMillis(); System.out.println("test 1 (try/catch) = "+(stop1-start1) ); System.out.println("test 2 (hjemmelavet)= "+(stop2-start2) ); System.out.println("test 3 (isDigit() ) = "+(stop3-start3) ); }
Som sagt try/catch skal kun bruges til 'exceptions' altså tilfælde man IKKE kan beskytte sig imod på forhånd, f.eks. at en socket forbindelse mistes osv.
Jeg mener bare at testen næsten er nyttesløs hvis ikke man fortager konverteringen bagefter. Spørgsmålet er så hvor lang tid det tager parseInt at køre hvis man først har sikret sig at strengen kun indeholder tal.
ja jeg må skuffe dig så bliver det bare endnu værrere:
test 1 (try/catch) = 842 test 2 (hjemmelavet)= 10 test 3 (isDigit() ) = 50
/** * Created by IntelliJ IDEA. * User: Søren Reinke * Date: Apr 8, 2003 * Time: 12:21:38 AM * To change this template use Options | File Templates. */ public class Benchmark { private static final int antal=100000;
private static final String text="0123456a789";
public Benchmark() { long start1=System.currentTimeMillis(); for(int x=0;x<antal;x++) { int tal=test1(text); } long stop1=System.currentTimeMillis(); long start2=System.currentTimeMillis(); for(int x=0;x<antal;x++) { int tal=test2(text); } long stop2=System.currentTimeMillis(); long start3=System.currentTimeMillis(); for(int x=0;x<antal;x++) { int tal=test3(text); } long stop3=System.currentTimeMillis(); System.out.println("test 1 (try/catch) = "+(stop1-start1) ); System.out.println("test 2 (hjemmelavet)= "+(stop2-start2) ); System.out.println("test 3 (isDigit() ) = "+(stop3-start3) ); }
private int test1(String t) { try { int tal=Integer.parseInt(t); } catch (NumberFormatException e) { return -1; } return Integer.parseInt(t); }
Jeg laver den samme konvertering på 3 forskellige måder netop for at fremhæve din løsning er performance mæssigt en særdeles dårlig ide. Så selvfølgelig gentager jeg det igen mange gange, og på flere måder for at understrege min påstand. Er det ikke nærmere dig der ikke vil acceptere din løsning er brugbar bare ikke særlig smart ?
At det sidste eksempel viste det rigtigt meget skyldes at de store tal bestående af 100 cifre alligevel ikke kan være i en int, så derfor er længden af strengen kortet ned til en størrelse der er realistisk.
fair nok :) private int test1(String t) { int tal; try { tal=Integer.parseInt(t); } catch (NumberFormatException e) { tal=-1; } return tal; }
Dog er try/catch metoden stadigvæk en del langsomere, her er tallene ved 1000000 gennemløb: test 1 (try/catch) = 7641 test 2 (hjemmelavet)= 90 test 3 (isDigit() ) = 420
Som sagt kan try/catch sagtens bruges i en håndevending, men tilrådeligt er det bestemt ikke. Jeg kan ikke huske hvad det specifik er en try/catch gør på JVM niveau, men der sker en hel del nede i JVM'en
Arne: try/catch er minimalt hurtigere end test2 hvis der ikke opstår fejl. Vi snakker om 30 ms ved 1*10^6 tests på en P4 1.7 GHz
Her er resultatet fra 1*10^6 tests hvor strengen indenholder '-123456789' test 1 (try/catch) = 661 test 2 (hjemmelavet)= 701 test 3 (isDigit() ) = 1081
Her hvor der er et bogstav: -123456789a test 1 (try/catch) = 7771 test 2 (hjemmelavet)= 120 test 3 (isDigit() ) = 501
Hvilket igen tydeligt viser, man skal ikke bruge try/catchs til den slags, da hvis man ryger ind i catch så betaler man dyrt i performance.
Rent performancemæssigt er prisen for at bruge test2 meget lille i forhold til prisen hvis test1 fejler.
Som sagt try/catch skal bruges til situationer hvor man ikke kan sikre at man ikke lander i catch på forhånd, da prisen er høj rent performance mæssigt.
Man skal over 1% i fejl hyppighed for a try-catch er langsommere.
1% fejl er absolut ikke urealistisk ved en manuel indtastning.
Men alt for stort ved læsning fra fil.
Jeg ville ikke optimere et program som skal læse 1 million tal fra en fil udfra en forudsætning om at der nok er over 10000 tal der p.g.a. fejl indeholder bogstaver.
og som sædvanligt bliver du ved og ved og ved og ved, kører du på duracell ?
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.