OVH Cloud OVH Cloud

Optimisation

23 réponses
Avatar
nico
Bonjour,

A titre d'entrainement j'ai ecrit la fonction suivante :

string xor_crypte(string str_in,string clef) {
int str_len=str_in.length();
int clef_len=clef.length();
string str_out;
for(int i=0;i<str_len;i+=clef_len) {
for(int j=0;j<clef_len;j++) {
char c[1]={ static_cast<char>(*str_in.substr(i+j,1).c_str()) ^
static_cast<char>(*clef.substr(j,1).c_str()) };
str_out+=string(c,1);
}
}
return str_out;
}

Que faudrait-il faire pour éventuellement l'optimiser ?
Peut être une conversion std::string > char * avant le for ?

--
nico

10 réponses

1 2 3
Avatar
Fabien LE LEZ
On Wed, 24 Nov 2004 23:01:34 +0100, "nico" :

Que faudrait-il faire pour éventuellement l'optimiser ?


1- Rajouter des espaces dans ton code. Tu y verras plus clair, nous
aussi, et ça ne ralentira en rien l'exécution.
2- Passer tes arguments par référence constante au lieu de les passer
par valeur.


--
;-)

Avatar
Matthieu Moy
"nico" writes:

Que faudrait-il faire pour éventuellement l'optimiser ?


A mon avis, avec des itérateurs sur les strings, tu gagnerais à la
fois en lisiblité et en vitesse.

En indentant avec plus d'un espace, tu gagnerais en lisibilité ;-)

Peut être une conversion std::string > char * avant le for ?


Si tu veux faire des .c_str(), oui, tu peux les factoriser, mais en
utilisant l'opérateur [] de std::string, (ou des itérateurs), tu n'en
a pas besoin.

Notes que tu as un opérateur

basic_string& operator+=(const charT* s)

donc, nul besoin de construire une string de taille 1 pour ajouter un
caractère à une string.

--
Matthieu

Avatar
nico
Tout d'abord merci de vos réponse.

Si tu veux faire des .c_str(), oui, tu peux les factoriser, mais en
utilisant l'opérateur [] de std::string, (ou des itérateurs), tu n'en
a pas besoin.
Puis-je avoir un exemple ? Merci.


basic_string& operator+=(const charT* s)
Ok


--
nico

Matthieu Moy wrote:
"nico" writes:

Que faudrait-il faire pour éventuellement l'optimiser ?


A mon avis, avec des itérateurs sur les strings, tu gagnerais à la
fois en lisiblité et en vitesse.

En indentant avec plus d'un espace, tu gagnerais en lisibilité ;-)

Peut être une conversion std::string > char * avant le for ?


Si tu veux faire des .c_str(), oui, tu peux les factoriser, mais en
utilisant l'opérateur [] de std::string, (ou des itérateurs), tu n'en
a pas besoin.

Notes que tu as un opérateur

basic_string& operator+=(const charT* s)

donc, nul besoin de construire une string de taille 1 pour ajouter un
caractère à une string.



Avatar
nico
1/ Ok, pour ce qui est des indentations elles apparraissent bien plus
clairement dans mon IDE désolé :/
2/ Ok merci.

--
nico

Fabien LE LEZ wrote:
On Wed, 24 Nov 2004 23:01:34 +0100, "nico" :

Que faudrait-il faire pour éventuellement l'optimiser ?


1- Rajouter des espaces dans ton code. Tu y verras plus clair, nous
aussi, et ça ne ralentira en rien l'exécution.
2- Passer tes arguments par référence constante au lieu de les passer
par valeur.



Avatar
Matthieu Moy
"nico" writes:

Tout d'abord merci de vos réponse.

Si tu veux faire des .c_str(), oui, tu peux les factoriser, mais en
utilisant l'opérateur [] de std::string, (ou des itérateurs), tu n'en
a pas besoin.
Puis-je avoir un exemple ? Merci.



Si tu veux le 42ème caractère (en partant de 0) de la chaine
ma_string, un ma_string[42] me parait simple et adapté ;-)

Pour ce qui est des itérateurs, tu peux écrire des choses comme

for (std::string::iterator i = ma_string.begin();
i := ma_string.end();
i++) {
... (*i) ... ;
}

En remplacant éventuellement iterator par const_iterator.

http://www.sgi.com/tech/stl/basic_string.html

--
Matthieu


Avatar
Fabien LE LEZ
http://www.giromini.org/usenet-fr/repondre.html

--
;-)
Avatar
Richard Delorme
Bonjour,

A titre d'entrainement j'ai ecrit la fonction suivante :

string xor_crypte(string str_in,string clef) {
int str_len=str_in.length();
int clef_len=clef.length();
string str_out;
for(int i=0;i<str_len;i+=clef_len) {
for(int j=0;j<clef_len;j++) {
char c[1]={ static_cast<char>(*str_in.substr(i+j,1).c_str()) ^
static_cast<char>(*clef.substr(j,1).c_str()) };
str_out+=string(c,1);
}
}


static_cast<char>(*str_in.substr(i+j,1).c_str() est une façon compliqué
d'écrire : str_in.at(i + j) ou str_in[i + j], si la vérification de
l'index était inutile.

En plus ce programme est erroné, car i + j peut être "out of range",
c'est-à-dire plus grand que str_len.
Une écriture un peu plus optimale et correcte de la boucle pourrait être:

for (int i = 0; i < str_len; ++i) {
const int j = i % clef_len;
str_out.append(1, str_in[i] ^ clef[j]);
}


return str_out;
}

Que faudrait-il faire pour éventuellement l'optimiser ?


Eviter au maximum la création de variables intermédiaires et les copies
de chaînes inutiles, en utilisant des références et, si possible, un
cryptage en place. Peut être utiliser des itérateurs.

Peut être une conversion std::string > char * avant le for ?


Non.

--
Richard

Avatar
Vincent Lascaux
"Richard Delorme" a écrit dans le message de news:
41a5142d$0$10781$
Bonjour,

A titre d'entrainement j'ai ecrit la fonction suivante :

string xor_crypte(string str_in,string clef) {
int str_len=str_in.length();
int clef_len=clef.length();
string str_out;
for(int i=0;i<str_len;i+=clef_len) {
for(int j=0;j<clef_len;j++) {
char c[1]={ static_cast<char>(*str_in.substr(i+j,1).c_str()) ^
static_cast<char>(*clef.substr(j,1).c_str()) };
str_out+=string(c,1);
}
}


static_cast<char>(*str_in.substr(i+j,1).c_str() est une façon compliqué
d'écrire : str_in.at(i + j) ou str_in[i + j], si la vérification de
l'index était inutile.

En plus ce programme est erroné, car i + j peut être "out of range",
c'est-à-dire plus grand que str_len.
Une écriture un peu plus optimale et correcte de la boucle pourrait être:

for (int i = 0; i < str_len; ++i) {
const int j = i % clef_len;
str_out.append(1, str_in[i] ^ clef[j]);
}


Il me semble que l'utilisation de l'operateur += est plus idiomatique (enfin
moi je la trouve plus lisible)... str_out += str_in[i] ^ clef[j];


Avatar
nico
Richard Delorme wrote:
Bonjour,

A titre d'entrainement j'ai ecrit la fonction suivante :

string xor_crypte(string str_in,string clef) {
int str_len=str_in.length();
int clef_len=clef.length();
string str_out;
for(int i=0;i<str_len;i+=clef_len) {
for(int j=0;j<clef_len;j++) {
char c[1]={ static_cast<char>(*str_in.substr(i+j,1).c_str()) ^
static_cast<char>(*clef.substr(j,1).c_str()) };
str_out+=string(c,1);
}
}


static_cast<char>(*str_in.substr(i+j,1).c_str() est une façon
compliqué d'écrire : str_in.at(i + j) ou str_in[i + j], si la
vérification de l'index était inutile.

En plus ce programme est erroné, car i + j peut être "out of range",
c'est-à-dire plus grand que str_len.
Une écriture un peu plus optimale et correcte de la boucle pourrait
être:
for (int i = 0; i < str_len; ++i) {
const int j = i % clef_len;
str_out.append(1, str_in[i] ^ clef[j]);
}



Ok merci, je ne savais pas que l'on pouvais traiter les objets string comme
des tableaux !

return str_out;
}

Que faudrait-il faire pour éventuellement l'optimiser ?


Eviter au maximum la création de variables intermédiaires et les
copies de chaînes inutiles, en utilisant des références et, si
possible, un cryptage en place. Peut être utiliser des itérateurs.

Peut être une conversion std::string > char * avant le for ?


Non.



J'obtiens donc une version optimisée ressemblant à ceci :

string xor_crypte(string *str_in,string *clef) {
int str_len=str_in->length();
int clef_len=clef->length();
string str_out;
for(int i=0;i<str_len;i++) {
int j=i % clef_len;
str_out.append(1,(*str_in)[i] ^ (*clef)[j]);
}
return str_out;
}


Merci ce fut très instructif.


Avatar
Fabien LE LEZ
On Thu, 25 Nov 2004 00:31:20 +0100, "nico" :

J'obtiens donc une version optimisée ressemblant à ceci :

string xor_crypte(string *str_in,string *clef) {


Uh ? Où as-tu vu ce genre de choses ?


string xor_crypte (string const& str_in, string const& clef)
{...

--
;-)

1 2 3