[Perf] Optimiser la lecture d'un fichier de taille > 2 m
bnjr
je devlp actuellement une application de decodage d'un format BER (basic encoded rule standard ASN.1)
mon application doit avoir un temp de reponse < 2min
mon probleme que la lecture depuis un fichier (java.io.*) avec le langage java s' avere tres lente (jvm+io+...) > 20min (si le fichier depasse les 2mo ) en plus du traitement de decodage sur le fichier >4min
si qql coné une solution autre que l'utilisation des stream????
voici le code en question!!!
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| //******************************************************
......
StringBuffer contenu = new StringBuffer();
try {
FileInputStream in = new FileInputStream(infile);
BufferedInputStream bfin = new BufferedInputStream(in);
FileOutputStream out = new FileOutputStream(outfile);
BufferedOutputStream bfout = new BufferedOutputStream(out);
int myread;
// lecture du contenu du fichier cdr
while ((myread = bfin.read()) != -1)
{
contenu.append((char) myread);
}
// mettre le buffer string contenu dans une string tmp
String tmp = "";
for (int i = 0; i < contenu.length(); i++) {
tmp += contenu.charAt(i);
}
........
//*************************************************** |
[Modéré par Didier] : ajout de tag dans le titre - Les règles du forum Java
Re: comment optimiser la lecture d'un fichier de taille >
Salut,
Penses à mettre toi même les balises [ code ] la prochaine fois... c'est plis lisible ;)
Maintenant pourquoi est-ce que tu fais ca :
Code:
1 2 3 4 5 6 7 8
|
// mettre le buffer string contenu dans une string tmp
String tmp = "";
for (int i = 0; i < contenu.length(); i++) {
tmp += contenu.charAt(i);
} |
L'opérateur + sur les String (ou += qui revient au même) ne dois JAMAIS être utilisé dans une boucle car cela implique la création/destruction de chaine temporaire à chaque tour ce qui est très lent...
Dans ces cas là il faut utiliser un StringBuffer !!!!!!!!
En plus tu l'utilises déjà pour la lecture du fichier !!!! Je suis sûr que la boucle de lecture du fichier est + rapide que cette boucle là !!!!
Si tu veux 'convertir' ton StringBuffer en String, il suffit d'utiliser la méthode toString() qui elle est optimisé (pas de création d'une nouvelle chaine si le StringBuffer n'est plus modifié par la suite) :
Code:
String tmp = contenu.toString();
a++
Re: comment optimiser la lecture d'un fichier de taille >
je ne crois pas que cette boucle est responsable de la lenteur du prog
car j'ai tester deja le code sans cette boucle,,,elle ne sert absolument a rien!!!!
pour la lecture d'un bloc de 5000 à travers la methode read(byte[] b)
en qoui ca pourrait ameliorer le tmp de rep???
puisseque je croi que le nombre d'acces au disque reste le meme.........
.
Re: comment optimiser la lecture d'un fichier de taille >
Citation:
Envoyé par sacofan
je ne crois pas que cette boucle est responsable de la lenteur du prog
car j'ai tester deja le code sans cette boucle,,,elle ne sert absolument a rien!!!!
Et moi je ne crois pas : j'en suis sûr !!!
Entoure la de System.currentTimeMillis() pour voir le temps qu'elle met...
Citation:
Envoyé par sacofan
pour la lecture d'un bloc de 5000 à travers la methode read(byte[] b)
en qoui ca pourrait ameliorer le tmp de rep???
puisseque je croi que le nombre d'acces au disque reste le meme.........
C'est différent de lire 2 000 000 fois 1 caractères que de lire 400 fois 5000 caractères...
C'est l'accès au disque qui est le plus lent... La lecture est plus rapide.
Donc pour de gros fichiers c'est préférable de lire par bloc plutot que caractère par caractère...
Mais tu n'as pas besoin de le faire car c'est déjà fait par le BufferedInputStream. Par contre tu peux augmenter la taille de son buffer comme l'indique jowo...
Ce que tu pourrais encore faire, même le gain ne sera pas forcément très grand, c'est d'initialisé ton StringBuffer à la taille de ton fichier...
Re: comment optimiser la lecture d'un fichier de taille >
Citation:
Envoyé par adiGuba
Citation:
Envoyé par sacofan
je ne crois pas que cette boucle est responsable de la lenteur du prog
car j'ai tester deja le code sans cette boucle,,,elle ne sert absolument a rien!!!!
Et moi je ne crois pas :
j'en suis sûr !!!
Entoure la de
System.currentTimeMillis() pour voir le temps qu'elle met...
Citation:
Envoyé par sacofan
pour la lecture d'un bloc de 5000 à travers la methode read(byte[] b)
en qoui ca pourrait ameliorer le tmp de rep???
puisseque je croi que le nombre d'acces au disque reste le meme.........
C'est différent de lire 2 000 000 fois 1 caractères que de lire 400 fois 5000 caractères...
C'est l'accès au disque qui est le plus lent... La lecture est plus rapide.
Donc pour de gros fichiers c'est préférable de lire par bloc plutot que caractère par caractère...
Mais tu n'as pas besoin de le faire car c'est déjà fait par le
BufferedInputStream. Par contre tu peux augmenter la taille de son buffer comme l'indique
jowo...
Ce que tu pourrais encore faire, même le gain ne sera pas forcément très grand, c'est d'initialisé ton StringBuffer à la taille de ton fichier...
ok merci je crois que ca marche
j'ai suivi les 2 astuces
j'ai obtenu un temp de reponse < 1min
ca donne ca:
//***********************************************************
try {
FileInputStream in = new FileInputStream(infile);
BufferedInputStream bfin = new BufferedInputStream(in,2*1024*1024);
FileOutputStream out = new FileOutputStream(outfile);
BufferedOutputStream bfout = new BufferedOutputStream(out);
int myread;
// lecture du contenu du fichier cdr
byte[] b=new byte[1024];
while ((myread = bfin.read(b)) != -1)
{
for (int jjj=0;jjj<1024;jjj++) {
myread=(int)b[jjj];
contenu.append((char) myread);
}
}
////////////////////////***