Java: float wird langsamer bearbeitet als double *gelöst*?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
weedy
Beiträge: 585
Registriert: 02.11.2002 21:47:49
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Java: float wird langsamer bearbeitet als double *gelöst*?

Beitrag von weedy » 29.08.2004 18:23:23

Gibt es einen verständlichen Grund dafür?

Hier eine kleine Testapplikation:

Code: Alles auswählen

public class Test
{
 public static void main( String[] args)
 {

  for( int k= 0; k< 3; k++) // k-Schleife
  {
   long t1= System.currentTimeMillis();

   {
    float a= 1;
    for( int i= 0; i< 10000000; i++)
     a*=1.0000001;

    //System.out.println( ""+ a);
   }

   long t2= System.currentTimeMillis();

   {
    double a= 1;
    for( int i= 0; i< 10000000; i++)
     a*=1.0000001;

    //System.out.println( ""+ a);
   }

   long t3= System.currentTimeMillis();

   System.out.println( ""+ ( t2- t1)); // java1.1.8: 788/ 1052 in k schleife, java1.4: 236/ 193 in k
   System.out.println( ""+ ( t3- t2)); // java1.1.8: 734/ 708 in k schleife, java1.4: 113/ 110 in k
  }
 }
}

Interessanterweise ist unter java1.1.8 der erstere Wert deutlich schneller, wenn man die k-Schleife auskommentiert. Kann das jemand bestätigen? Ich kann mir das vor allem nicht erklären.

Nachtrag: Ich habe jetzt aber eine Idee dazu: es könnte sein, daß (für den unteren Fall, nicht das Hauptthema double<->float) k ein 'CPU'-Register in der VM reserviert, auf welchem vorher a lag. 'a' ist im langsameren Fall im Speicher.

weedy.
Zuletzt geändert von weedy am 05.09.2004 14:40:27, insgesamt 2-mal geändert.

Benutzeravatar
Dookie
Beiträge: 1104
Registriert: 17.02.2002 20:38:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von Dookie » 29.08.2004 20:18:04

Hi weedy,

es könnte auch daran lieben, daß du im code a*=1.0000001; also a mit einem Float multiplizierst, der muss im 2. Fall erst in einen Double umgewandelt werden.


Gruß

Dookie

Benutzeravatar
weedy
Beiträge: 585
Registriert: 02.11.2002 21:47:49
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Beitrag von weedy » 29.08.2004 21:05:12

Danke für den Tip. Die Zahl 1.0000001 ist unter Java per Default ein double. Ich habe interessehalber mal 1.0000001 durch 1.0000001f ersetzt; das Nebenproblem verschwindet dabei (k), und double multipliziert mit dieser Zahl ist nur geringfügig schneller als eine Multiplikation von einem float mit dieser Zahl.

Code: Alles auswählen

 // a*=1.0000001:
 // float a:
 // java1.1.8: 788/ 1052 in k schleife, java1.4: 236/ 193 in k
 // double a
 // java1.1.8: 734/ 708 in k schleife, java1.4: 113/ 110 in k

 // a*=1.0000001f:
 // float a:
 // java1.1.8: 841/ 813 in k schleife, java1.4: 107/ 98 in k
 // double a:
 // java1.1.8: 655/ 680 in k schleife, java1.4: 103/ 106 in k
=> unter Java immer double benutzen, auch wenn man float nehmen könnte.

weedy.

Benutzeravatar
weedy
Beiträge: 585
Registriert: 02.11.2002 21:47:49
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Beitrag von weedy » 30.08.2004 17:21:13

Interessanterweise ist das auch in c so (hätt ich mir eigentlich denken können):

Code: Alles auswählen

#include <stdio.h>

#include <sys/time.h>
#include <time.h>

typedef struct timeval t_timeval;

long long assemble( t_timeval tv){ return tv.tv_sec*1000000LL+ tv.tv_usec;}

int main( int argc, char** argv)
{

 t_timeval tv1;
 t_timeval tv2;
 t_timeval tv3;

 gettimeofday( &tv1, NULL);

 {
  float a= 1;
  int i= 0;
  for( i= 0; i< 100000000; i++) a*=1.0000001;
 }

 gettimeofday( &tv2, NULL);

 {
  double a= 1;
  int i= 0;
  for( i= 0; i< 100000000; i++) a*=1.0000001;
 }

 gettimeofday( &tv3, NULL);

 printf( "%lld\n", assemble( tv2)- assemble( tv1)); // 1050011
 printf( "%lld\n", assemble( tv3)- assemble( tv2)); // 961722

 return 0;
}
weedy.

Benutzeravatar
Dookie
Beiträge: 1104
Registriert: 17.02.2002 20:38:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von Dookie » 30.08.2004 17:31:07

Liegt auch nicht an der Sprache sondern am Prozessor, moderne Prozessoren verwenden intern immer 64 oder mehr bit bei Fließkommazahlen. Daher sollte man, solange nicht am Speicher gespart werden soll Double statt Float verwenden. Python z.B. kennt nur einen Float-Type, der ist aber eigentlich ein Double.


Gruß

Dookie

Antworten