# Ein Sack voll Zahlen



## RedHawk123 (7. Jan 2018)

Hey, 

```
class Effizienzvergleicher
{
    /**
     * Vergleicht die Effizienz verschiedener Implementationen von Zahlensack.
     * Alle Zahlensaecke werden mit der gleichen Groesse erzeugt.
     *
     * @param groesse die Groesse der Zahlensaecke
     */
    public void vergleiche(int groesse)
    {
        if (groesse < 1)
        {
            throw new IllegalArgumentException("groesse < 1");
        }
       
        // Hier der dynamische vs statische Typ!
        Zahlensack zs = new Naiv(groesse);
        vermesse(zs);
       
        zs = new Permutation(groesse);
        vermesse(zs);
       
        zs = new Auswahl(groesse);
        vermesse(zs);
    }

    /**
     * Misst die Zeit, die fuer das Entfernen von sehr vielen Zahlen aus dem
     * Zahlensack benoetigt wird. Das Ergebnis wird auf der Konsole ausgegeben.
     *
     * @param sack der zu vermessende Zahlensack
     */
    public void vermesse(Zahlensack sack)
    {
       
// Speichere die aktuelle Zeit als Startzeit

        // Rufe 1 Mio. Mal "entferneZahl" auf

        // Speichere die aktuelle Zeit als Stoppzeit

        // Bilde die Differenz aus Stoppzeit und Startzeit
       
        // Teile die Differenz durch 1000000, um von ns nach ms umzurechnen

        System.out.print(sack); // Beschreibung des Zahlensacks ausgeben
        System.out.print(": "); // gefolgt von einem Doppelpunkt
        // Gib das Ergebnis auf der Konsole aus
    }
}
```

Also meine Aufgabe ist es die Methode "vermesse" zu ergänzen. Dazu soll auf "long System.nanoTime()" zurückgreifen, welche die aktuelle Zeit in
Nanosekunden liefert.

Mein Hinweis von der Aufgabe ist: 
_Um vernünftige Messergebnisse zu erhalten ist es notwendig, sehr viele
Methodenaufrufe durchzuführen. Verwendet dazu eine Zählschleife. Anschließend soll das Messergebnis
einfach auf die Konsole geschrieben werden, sinnvollerweise in der Einheit ms._

Ich habe ehrlich gesagt keine Ahnung wie ich das machen soll und hoffe dass mir hier jemand helfen kann.


----------



## Robat (7. Jan 2018)

So absolut gar keine Idee?
Hier mal ein paar Anregungen :

```
// Differenz bilden
int a = 5;
int b = 4;
int differenz = a - b;

// Zählschleife
for(int i=0; i < 100; i++) {
    // Do something
}

// Systemzeit speichern
long time = System.nanoTime();
```


----------



## RedHawk123 (8. Jan 2018)

Vielen dank für deine Hilfe!


Robat hat gesagt.:


> So absolut gar keine Idee?
> Hier mal ein paar Anregungen :
> 
> ```
> ...



Ich habe es so probiert:

```
class Effizienzvergleicher
{
    private long lastTime; //hier kann ich den wert aus meiner schleife dann auch ausserhalb der Schleife nutzen
    private long _groesse; //damit kann ich auch die Sackgroesse innerhalb der Methode vermesse nutzen
   
    /**
     * Vergleicht die Effizienz verschiedener Implementationen von Zahlensack.
     * Alle Zahlensaecke werden mit der gleichen Groesse erzeugt.
     *
     * @param groesse die Groesse der Zahlensaecke
     */
    public void vergleiche(int groesse)
    {
        if (groesse < 1)
        {
            throw new IllegalArgumentException("groesse < 1");
        }

        _groesse = groesse;
        // Hier der dynamische vs statische Typ!
        Zahlensack zs = new Naiv(groesse);
        vermesse(zs);
       
        zs = new Permutation(groesse);
        vermesse(zs);
       
        zs = new Auswahl(groesse);
        vermesse(zs);
    }

    /**
     * Misst die Zeit, die fuer das Entfernen von sehr vielen Zahlen aus dem
     * Zahlensack benoetigt wird. Das Ergebnis wird auf der Konsole ausgegeben.
     *
     * @param sack der zu vermessende Zahlensack
     */
    public void vermesse(Zahlensack sack)
    {
        long firstTime = System.nanoTime(); // Speichere die aktuelle Zeit als Startzeit
        long sackgroesse = _groesse;
        for(long i=0; i< sackgroesse; i++)
        {
            sack.entferneZahl();        // Rufe 1 Mio. Mal "entferneZahl" auf
            long lastTime = System.nanoTime();        // Speichere die aktuelle Zeit als Stoppzeit
        }
        long time = firstTime - lastTime/1000000;         // Bilde die Differenz aus Stoppzeit und Startzeit
         // Teile die Differenz durch 1000000, um von ns nach ms umzurechnen
        System.out.print(sack); // Beschreibung des Zahlensacks ausgeben
        System.out.print(":"+ time +"    "); // gefolgt von einem Doppelpunkt
        // Gib das Ergebnis auf der Konsole aus
       
    }
}
```
_(Habe vergessen zu erwähnen dass "entferneZahl" eine Methode ist, die den Sack immer eine Zahl beim Herausziehen entnimmt.)_
Hab ich es raus oder irre ich mich und wieso steht im Kommentar rufe 1mio mal entferne Zahl auf. Geht dass nicht auch einfach innerhalb der zählschleife? 

danke im voraus!


----------



## fhoffmann (8. Jan 2018)

RedHawk123 hat gesagt.:


> public void vermesse(Zahlensack sack, int Volumen)


Warum hast du denn deiner Methode eine weiteren Parameter gegeben (und Parameter/Variablen sollte man klein schreiben)? Wie rufst du denn die Methode auf?
Einfacher wäre es doch so:

```
public void vermesse(Zahlensack sack) {
   int volumen = 1000000;
   // u.s.w.
}
```
Und der Rest dürfte noch nicht einmal compilieren, da die Variable lastTime außerhalb der Schleife nicht bekannt ist.
Schließlich kennt auch Java die Regel "Punktrechnung vor Strichrechnung"!


----------



## RedHawk123 (8. Jan 2018)

fhoffmann hat gesagt.:


> Warum hast du denn deiner Methode eine weiteren Parameter gegeben (und Parameter/Variablen sollte man klein schreiben)? Wie rufst du denn die Methode auf?
> Einfacher wäre es doch so:
> 
> ```
> ...


Tut mir leid! ich habe gerade mein Kommentar geändert und den kompletten quelltext reinkopiert. 
Also wir dürfen den Sack keinen konstanten wert geben, dies tut der Nutzer selber..


----------



## Meniskusschaden (8. Jan 2018)

RedHawk123 hat gesagt.:


> Ist das so richtig gedacht?


Nein. `entferneZahl()` soll 1 Mio. mal und nicht `Volumen` mal aufgerufen werden. Wo kommt das Methodenargument `Volumen` überhaupt pötzlich her? In Post #1 war es noch nicht da. Die Berechnung von `time` ist auch falsch. Außerdem: warum rufst du `System.nanoTime()` denn so oft auf? Zweimal würde doch auch genügen.


RedHawk123 hat gesagt.:


> Ich finde es komisch warum als Kommentar "rufe 1 mio.mal entferneZahl auf" steht, da man dass doch auch so machen kann oder nicht?


Vermutlich wollte der Aufgabensteller dir ersparen, selbst nachdenken zu müssen, denn es hätte genügt, einfach jeden Kommentar durch die entsprechenden Java-Anweisungen zu ersetzen.


----------



## RedHawk123 (8. Jan 2018)

Meniskusschaden hat gesagt.:


> Nein. `entferneZahl()` soll 1 Mio. mal und nicht `Volumen` mal aufgerufen werden. Wo kommt das Methodenargument `Volumen` überhaupt pötzlich her? In Post #1 war es noch nicht da. Die Berechnung von `time` ist auch falsch. Außerdem: warum rufst du `System.nanoTime()` denn so oft auf? Zweimal würde doch auch genügen.
> 
> Vermutlich wollte der Aufgabensteller dir ersparen, selbst nachdenken zu müssen, denn es hätte genügt, einfach jeden Kommentar durch die entsprechenden Java-Anweisungen zu ersetzen.


Und wie sieht es dann so aus??

```
public void vermesse(Zahlensack sack)
    {
        long firstTime = System.nanoTime(); // Speichere die aktuelle Zeit als Startzeit
        for(long i=0; i< 1000000; i++)
        {
            sack.entferneZahl();        // Rufe 1 Mio. Mal "entferneZahl" auf
        }
        long lastTime = System.nanoTime();        // Speichere die aktuelle Zeit als Stoppzeit
        long time = (lastTime - firstTime)/1000000;         // Bilde die Differenz aus Stoppzeit und Startzeit
         // Teile die Differenz durch 1000000, um von ns nach ms umzurechnen
        System.out.print(sack); // Beschreibung des Zahlensacks ausgeben
        System.out.print(":"+ time +"    "); // gefolgt von einem Doppelpunkt
        // Gib das Ergebnis auf der Konsole aus
     
    }
```


----------



## Meniskusschaden (8. Jan 2018)

RedHawk123 hat gesagt.:


> Und wie sieht es dann so aus?


Besser. Die Berechnung der Laufzeit ist aber immer noch falsch.


----------



## fhoffmann (8. Jan 2018)

Das sieht gut aus.


RedHawk123 hat gesagt.:


> // Gib das Ergebnis auf der Konsole aus


Allerdings fehlt nur noch diese Ausgabe!


----------



## RedHawk123 (8. Jan 2018)

fhoffmann hat gesagt.:


> Das sieht gut aus.
> 
> Allerdings fehlt nur noch diese Ausgabe!





Meniskusschaden hat gesagt.:


> Besser. Die Berechnung der Laufzeit ist aber immer noch falsch.


Super! Vielen Dank für eure Hilfe von euch dreien und für euer Verständnis für Anfänger!

Gruß RedHawk


----------



## Meniskusschaden (8. Jan 2018)

Meniskusschaden hat gesagt.:


> Besser. Die Berechnung der Laufzeit ist aber immer noch falsch.


Ist doch richtig. Hatte wohl noch mal den Code vom vorigen Posting angesehen.


----------

