HaveuBreak !!

Ahhhh!!! Enfin quelque chose d'utile sur ce site!!! Je me suis amusé à développer une petite application qui permet aux gens de se réunir pour la pause au travail ;) Elle permet d'être notifié lorsqu'un collègue va en pause, ou bien de demander une pause de toute urgence alors que les copains sont dans des bureaux à l'opposé du bâtiment..
Cette application est un freeware sans licence. Néanmoins, elle utilise la librairie JGroups et des icônes de la collection famfamfam silk qui sont soumis à leurs propres copyright.

  • error.png Attention : si cette application ne fonctionne pas sur votre ordinateur, il est possible que votre réseau soit mal configuré pour le multicast ou bien que la politique de sécurité de votre entreprise ne vous autorise pas à l'utiliser.

haveubreak-screenshot.jpg

Télécharger

Sources (projets Netbeans et Eclipse)

Attention : pour compiler les sources et distribuer, vous avez besoin de la librairie JGroups (vers 2.8 au moins)

[Java] Performances en Java - Singleton et synchronisation

Test du pattern Singleton, avec la notion d'accès synchronisés. Ce test met en œuvre trois solutions :

  • La classe A utilise un getInstance synchronisé
  • La classe B utilise un getInstance non-synchronisé, où seul la partie d'instanciation est synchronisée
  • La classe C ne se soucie pas de la synchronisation car l'instantiation est statique
 public class SynchronizeBench2 {
   static class A {
     private static A instance = null;
     private A() {
       System.out.println("New A");
     }
     public static synchronized A getInstance() {
       if (instance == null) {
         instance = new A();
       }
       return instance;
     }
   }
   static class B {
     private static B instance = null;
     private B() {
       System.out.println("New B");
     }
     public static B getInstance() {
       if (instance == null) {
         synchronized (B.class) {
           if (instance == null) {
             instance = new B();
           }
         }
       }
       return instance;
     }
   }
   static class C {
     private static C instance = new C();
     private C() {
       System.out.println("New C");
     }
     public static C getInstance() {
       return instance;
     }
   }
   public static void main(String args) {
 
     int i = 10000000;
     long time = System.currentTimeMillis();
     while (i > 0) {
       A.getInstance();
       i--;
     }
     System.out.println("Test A : "+(int)(System.currentTimeMillis()-time)+" ms");
 
     i = 10000000;
     time = System.currentTimeMillis();
     while (i > 0) {
       B.getInstance();
       i--;
     }
     System.out.println("Test B : "+(int)(System.currentTimeMillis()-time)+" ms");
 
     i = 10000000;
     time = System.currentTimeMillis();
     while (i > 0) {
       C.getInstance();
       i--;
     }
     System.out.println("Test C : "+(int)(System.currentTimeMillis()-time)+" ms");
 
   }
 
 }

Résultats

  • Classe A : entre 327 et 350 millisecondes
  • Classe B : entre 62 et 73 millisecondes
  • Classe C : entre 94 et 109 millisecondes

On remarque que la première solution est de loin la plus mauvaise : synchroniser la méthode entière oblige la machine virtuelle a mettre en œuvre le principe de synchronisation à chaque appel, ce qui dégrade les performances. La seconde méthode est bien meilleure, le bloc synchronisé étant accédé uniquement si l'instance n'a pas été crée. Bizarrement, la dernière méthode n'est pas la plus performante alors que théoriquement elle devrais être la plus rapide (moins de test et pas de synchronisation).

[Java] Performances en Java - L'influcence du mot clé synchronized (1)

Le mot clé synchronized permet de s'assurer qu'une méthode ou un bloc de code se sera pas accédé par deux Thread en même temps. Pour plus de détails, voyez cet article sur Développez.com[htt.... Voici le test effectué :

public class SynchronizeBench {
 
    public SynchronizeBench() {
    }
 
    public void a() {
    }
 
    public synchronized void b() {
    }
 
    static void test(SynchronizeBench bench, boolean a) {
      int i = 500000;
      long time = System.currentTimeMillis();
      while (i > 0) {
        if (a) {
          bench.a();
        } else {
          bench.b();
        }
        i--;
      }
      time = System.currentTimeMillis() - time;
      System.out.println("Methode "+(a?"a":"b")+" : "+time+" ms");
    }
 
    public static void main(String[] args) {
      SynchronizeBench bench = new SynchronizeBench();
      test(bench, true);
      test(bench, false);
    }
 
  }

Résultats

  • Méthode a (sans synchronisation) : 0 miilisecondes
  • Méthode b (avec synchronisation) : entre 14 et 17 millisecondes

Conclusion

L'utilisation du mot clé synchronized ralenti en soi l'accès à une méthode.

[Java] Performances en Java - La construction de String

La construction de chaînes de caractères en Java peut être optimisée en utilisant les nouvelles classes incluses dans le JDK 1.5. Ce petit test compare trois méthodes différentes pour construire une chaîne de caractère de 50 000 entiers : - La méthode classique par concaténation de String (opérateur +=) - La classe StringBuilder, qui est spécialisée dans la construction de chaînes - La classe StringBuffer, qui est identique au StringBuilder avec en plus la notion de synchronisation

Voici le code utilisé :

static Runnable classic = new Runnable() {
    @Override
    public void run() {
      String s = "";
      for (int i = 0; i < 50000; i++) {
        int v = (int)(Math.random() * 9f);
        s += v;
      }
    }	
  };
 
  static Runnable stringBuilder = new Runnable() {
    @Override
    public void run() {
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < 50000; i++) {
        int v = (int)(Math.random() * 9f);
        sb.append(v);
      }
    }
  };
 
  static Runnable stringBuffer = new Runnable() {
    @Override
    public void run() {
      StringBuffer sb = new StringBuffer();
      for (int i = 0; i < 50000; i++) {
        int v = (int)(Math.random() * 9f);
        sb.append(v);
      }
    }
  };
 
  static void test(Runnable runnable, String msg) {
    long time = System.currentTimeMillis();
    runnable.run();
    time = System.currentTimeMillis() - time;
    System.out.println(msg+" : "+time+" ms");
  }
 
  public static void main(String[] args) {
    System.out.println("TEST PERFORMANCES String");
    test(classic, "Methode classique");
    test(stringBuilder, "Methode StringBuilder");
    test(stringBuffer, "Methode StringBuffer");
  }

Les résultats sont sans équivoques :

  • Méthode classique : entre 2000 et 2200 millisecondes
  • Méthode StringBuilder : entre 0 et 16 millisecondes
  • Méthode StringBuffer : entre 0 et 16 millisecondes

La méthode classique est véritablement bien plus lente. Concernant les deux méthodes StringBuilder et StringBuffer, il est difficile de les différencier avec ce test, mais elles sont néanmoins bien plus performantes que la méthode classique.

 Ce test a été réalisé sur un pc Intel Core2 Duo 2.66GHz
 avec 2Go de RAM, Windows XP SP3 et JRE 1.6.0_07.

[Java] Matrices

Bon alors dans la série Java2D, aujourd'hui : les matrices.

Matrices usuelles


Matrice de rotation 2D



Matrice de rotation 3D autour de l'axe X


Matrice de rotation 3D autour de l'axe Y


Matrice de rotation 3D autour de l'axe Z


Outils Java

public static Matrix toMatrix(Vector3d v) {
return new Matrix(new double[][] {
new double[] { v.x },
new double[] { v.y },
new double[] { v.z }
});
}

Classe Matrix

Il s'agit d'une classe toute simple pour représenter une matrice ainsi que les opérations de bases (addition, multiplication, inversion et résolution avec l'algorithme de Gauss-Jordan). Si vous cherchez quelque chose de plus puissant regardez le Matrix Toolkit for Java

Télécharger le fichier Matrix.java

Afficher Matrix.java dans cette fenêtre
// Matrix.java
// a simple java file for a standard class


/**
* class Matrix
*/
public class Matrix{


// ===================================================================
// constants


// ===================================================================
// class variables

/** the number of rows. */
private int nRows;
/** the number of columns. */
private int nCols;

/** the element array of the matrix.*/
private double[][] el;

// ===================================================================
// constructors

/** Main constructor */

/**
* Construct a new Matrix, with 1 row and 1 column, initialized to 1.
*/
public Matrix(){
this(1, 1);
}

/** init a new Matrix with nbRows rows, and nbCols columns. */
public Matrix(int nbRows, int nbCols){
nRows = nbRows;
nCols = nbCols;
el = new double[nRows][nCols];
setToIdentity();
}

/**
* Construct a new Matrix, initialized with the given coefficients.
*/
public Matrix(double[][] coef){
if(coef==null){
nRows = 1;
nCols = 1;
el = new double[nRows][nCols];
setToIdentity();
return;
}

nRows = coef.length;
nCols = coef[0].length;
el = new double[nRows][nCols];
for(int r=0; r<nRows; r++)
for(int c=0; c<nCols; c++)
el[r][c] = coef[r][c];
}

public Matrix(Matrix m) {
this(m.el);
}


// ===================================================================
// accessors

/**
* return the coef. row and col are between 1 and the number of rows and columns.
*/
public double getCoef(int row, int col){
return el[row][col];
}

/** return the number of rows. */
public int getRows(){
return nRows;
}

/** return the number of columns. */
public int getColumns(){
return nCols;
}

/** return true if the matrix is square, i.e. the number of rows equals the number
* of columns. */
public boolean isSquare(){
return (nCols==nRows);
}



// ===================================================================
// modifiers

/**
* set the coef to the given value. row and col are between 1 and the
* number of rows and columns.
*/
public void setCoef(int row, int col, double coef){
el[row-1][col-1] = coef;
}

// ===================================================================
// computation methods

/**
* return the result of the multiplication of the matriux with another one.
* The content of the matrix is not modified.
*/
public Matrix multiplyWith(Matrix matrix){

//System.out.println(nCols+" != "+matrix.nRows);

// check sizes of the matrices
if(nCols != matrix.nRows){
System.out.println("Matrices size don't match ! ("+nCols+" != "+matrix.nRows+")");
return null;
}
double sum;

Matrix m = new Matrix(nRows, matrix.nCols);

for(int r=0; r<m.nRows; r++)
for(int c=0; c<m.nCols; c++){
sum=0;
for(int i=0; i<nCols; i++)
sum+=el[r][i]*matrix.el[i][c];
m.el[r][c] = sum;
}

return m;
}

/**
* return the result of the multiplication of the matrix with the given vector.
* The content of the matrix is not modified.
*/
public double[] multiplyWith(double [] coefs){

if(coefs==null){
System.out.println("no data to compute");
return null;
}

// check sizes of matrix and vector
if(coefs.length != nCols){
System.out.println("Matrices size don't match !");
return null;
}
double sum;
double[]res = new double[nRows];

for(int r=0; r<nRows; r++){
sum=0;
for(int c=0; c<nCols; c++)
sum+=el[r][c]*coefs[c];
res[r] = sum;
}
return res;
}

/**
* return the result of the multiplication of the matrix with the given vector.
* The content of the matrix is not modified.
*/
public double[] multiplyWith(double []src, double[]res){

if(src==null){
System.out.println("no data to compute");
return null;
}

// check sizes of matrix and vector
if(src.length != nCols){
System.out.println("Matrices size don't match !");
return null;
}
if(src.length != res.length)
res = new double[nRows];

double sum;

for(int r=0; r<nRows; r++){
sum=0;
for(int c=0; c<nCols; c++)
sum+=el[r][c]*src[c];
res[r] = sum;
}
return res;
}

/** transpose the matrix, changing the inner coefficients. */
public void transpose(){
int tmp = nCols;
nCols = nRows;
nRows = tmp;
double[][] oldData = el;
el = new double[nRows][nCols];

for(int r=0; r<nRows; r++)
for(int c=0; c<nCols; c++)
el[r][c] = oldData[c][r];
}

/** get the transposed matrix, without changing the inner coefficients
* of the original matrix. */
public Matrix getTranspose(){
Matrix mat = new Matrix(nCols, nRows);

for(int r=0; r<nRows; r++)
for(int c=0; c<nCols; c++)
mat.el[c][r] = el[r][c];
return mat;
}


/**
* compute the solution of a linear system, using the Gauss-Jordan algorithm. The
* inner coefficients of the matrix are not modified.
*/
public double[] solve(double vector []){

if(vector==null) throw new NullPointerException();
if(vector.length != nRows){
System.out.println("matrix and vector dimensions do not match!");
return null;
}
if(nCols != nRows){
System.out.println("Try to invert non square Matrix.");
return null;
}

double[] res = new double[vector.length];
for(int i=0; i<nRows; i++) res[i]=vector[i];

Matrix mat = new Matrix(el);

int r, c; // row and column indices
int p, r2; // pivot index, and secondary row index
double pivot, tmp;

// for each line of the matrix
for(r=0; r<nRows; r++){

p = r;
// look for the first non-null pivot
while((Math.abs(mat.el[p][r])<1e-15) && (p <= nRows))
p ++;

if(p==nRows){
System.out.println("Degenerated linear system :");
return null;
}

// swap the current line and the pivot
for(c=0; c<nRows; c++){
tmp = mat.el[r][c];
mat.el[r][c] = mat.el[p][c];
mat.el[p][c] = tmp;
}

// swap the corresponding values in the vector
tmp = res[r];
res[r] = res[p];
res[p] = tmp;

pivot = mat.el[r][r];

// divide elements of the current line by the pivot
for (c=r+1; c<nRows; c++)
mat.el[r][c] /= pivot;
res[r] /= pivot;
mat.el[r][r]=1;

// update other lines, before current line...
for (r2=0; r2<r; r2++){
pivot = mat.el[r2][r];
for(c=r+1; c<nRows; c++)
mat.el[r2][c] -= pivot*mat.el[r][c];
res[r2] -= pivot*res[r];
mat.el[r2][r] = 0;
}

// and after current line
for (r2=r+1; r2<nRows; r2++){
pivot = mat.el[r2][r];
for(c=r+1; c<nRows; c++)
mat.el[r2][c] -= pivot*mat.el[r][c];
res[r2] -= pivot*res[r];
mat.el[r2][r] = 0;
}
}

return res;
}

// ===================================================================
// general methods

/**
* Fill the matrix with zeros everywhere, except on the main diagonal, filled
* with ones.*/
public void setToIdentity(){
for(int r=0; r<nRows; r++)
for(int c=0; c<nCols; c++)
el[r][c] = 0;
for(int i=Math.min(nRows, nCols)-1; i>=0; i--)
el[i][i] = 1;
}

/**
* return a String representation of the elements of the Matrix
*/
public String toString(){
String res = new String("");
res = res.concat("Matrix size : " + Integer.toString(nRows) +
" rows and " + Integer.toString(nCols) + " columns.\n");
for(int r=0; r<nRows; r++){
for(int c=0; c<nCols; c++)
res = res.concat(Double.toString(el[r][c])).concat(" ");
res = res.concat(new String("\n"));
}
return res;
}
}

page 1 de 5