• [supprimé]

Bonjour,

Pour avoir une idée des performances de différents langages de programmation sur une petite épreuve portant sur des chaines de caractères j'ai fait passé un petit test répété un très grand nombre de fois.

J'obtiens les meilleurs résultats pour le C++ et le C. Mais le résultat le plus mauvais est obtenu avec le Swift d'Apple. Résultat pire que tous les autres derrière le PHP.

Je me dis que peut-être mon code en Swift n'est pas bon pour réaliser la tache.

1) une recherche de sous-chaine avec son extraction dans une autre chaine

2) un remplacement de toutes les occurrences d'un sous-chaine par une autre chaine

3) une suppression de tous les remplacements

C'est simple mais le code ainsi livré donne des performances lamentables :

func dotest()

{

let str : String = "bArakas mange barakas car boit barakas avec barakas"

let s1 : String = "ba"

let s2 : String = "ab"

//print(str);

var p : Int = 0

let b = str.endIndex

while( true )

{

let a = str.index( str.startIndex, offsetBy: p )

let r = a..<b

let x = str.range(of: s1 , options: NSString.CompareOptions.literal, range: r , locale: nil)

if( x == nil )

{

break ;

}

let z = str.substring(with: x! )

let y = str.distance(from: str.startIndex, to: (x?.lowerBound)!)

//print(y , " " , z)

p = ( y + s1.characters.count )

}

let str1 = str.replacingOccurrences(of: s1, with: s2 )

//print( str1 )

let str2 = str1.replacingOccurrences(of: s2, with: "" )

//print(str2 )

}

Peut-on faire autrement pour une meilleure performance ?

Le gros problème est qu'avec Swift il faut programmer l'indice qui va servir à indexer une chaine.

la même tache en Objective C donne un résultat moins mauvais.

Le résultat global sur 9 000 000 répétitions de la tache donne en ordre de performances décroissantes

1) C++

2) C

3) C++ avec QString de Qt

=== dans 5 sec de timer

4) Python

5) Pascal Object

==== dans 16 sec de timer

6) Objective C

7) Php

==== dans 30 sec de timer

8) Swift

==== avec 3 minutes de timer !!!

Cordialement.

Tu te poses des questions existentielles inutiles: tu choisis ton langage en fonction de tes besoins, et pas par "essai erreur" ... et en plus les perfs vont être également liées à l'OS & aux CPU, un RISC avec un OS "temps réel dur en C" restera quasi toujours imbattable sauf en affichage (du "rendering"): un simple windows avec une carte graphique de ouf avec proc 128bit même en Java/C# affichera & calculera plus vite .

Donc ta quête est sans espoir

  • [supprimé]

Tu te poses des questions existentielles inutiles: tu choisis ton langage en fonction de tes besoins, et pas par "essai erreur" ... et en plus les perfs vont être également liées à l'OS & aux CPU, un RISC avec un OS "temps réel dur en C" restera quasi toujours imbattable sauf en affichage (du "rendering"): un simple windows avec une carte graphique de ouf avec proc 128bit même en Java/C# affichera & calculera plus vite .

Donc ta quête est sans espoir

Bonjour,

Ce test n'a aucun rapport avec l'affichage. Je l'ai fait avec Mac OS et Linux. Le but est de vérifier les capacités sur des opérations basiques de chaines de caractères.

Le test porte sur les opérations sans affichage de manière à neutraliser l'aspect graphique et se concentrer sur le traitement. Ce n'est pas un test sur le choix d'un langage mais sur les performances relatives aux chaines de caractères.

Au fait comment améliorer le code Swift qui traine lamentablement ? Pour Swift je trouve que c'est handicapant d'avoir à programmer l'index pour ensuite l'appliquer à la chaine. Objective C fait de même mais avec un Range qui est légèrement moins lourd.

Par contre pour les autres langages c'est l'indexation directe de la chaine qui est bien plus performante.

Cordialement.

J'ai cherché à me renseigner sur swift.

Ca semble passer par une génération intermédiaire indépendante des machines, comme Java, avec de grosses librairies, mais ensuite cette représentation intermédiaire est compilée, contrairement à Java, censée donner de bonnes performances.

mais le fait qu'il n'optimise pas directement pour une machine cible peut expliquer ces problèmes de performances

ou ça peut être un problème de maturité. Java avait des perfos catastrophiques jusqu'à ce qu'ils introduise la compilation en temps réel

ça peut être aussi un problème de choix de l'outil swift, en fait de llvm sur lequel il se base, il semble y avoir une quantité de solutions existantes sur le langage, certaines passant par du C et j'imagine que les perfos peuvent être très différentes selon le système utilisé

je ne connais pas comment se situe celui d'Apple par rapport aux alternatives

http://llvm.org/

  • [supprimé]

J'ai cherché à me renseigner sur swift.

Ca semble passer par une génération intermédiaire indépendante des machines, comme Java, avec de grosses librairies, mais ensuite cette représentation intermédiaire est compilée, contrairement à Java, censée donner de bonnes performances.

mais le fait qu'il n'optimise pas directement pour une machine cible peut expliquer ces problèmes de performances

ou ça peut être un problème de maturité. Java avait des perfos catastrophiques jusqu'à ce qu'ils introduise la compilation en temps réel

ça peut être aussi un problème de choix de l'outil swift, en fait de llvm sur lequel il se base, il semble y avoir une quantité de solutions existantes sur le langage, certaines passant par du C et j'imagine que les perfos peuvent être très différentes selon le système utilisé

je ne connais pas comment se situe celui d'Apple par rapport aux alternatives

http://llvm.org/

Bonjour,

Ce n'est peut-être pas exact de dire que Swift est un nouveau langage. Il dépend à la fois de Objective C et de Clang. Dans certains cas certaines fonctionnalités ne font qu'envelopper des fonctionnalités de Objective C.

Par contre l'écriture est rendue parfois plus simple mais j'ai un doute sur les performances qui pourtant sont vantées par Apple.

Par contre j'ai été surpris de constater que pour mon test, Python qui est interprété a sensiblement les mêmes performances que le Pascal qui est compilé.

Cordialement.

Ce test n'a aucun rapport avec l'affichage. Je l'ai fait avec Mac OS et Linux. Le but est de vérifier les capacités sur des opérations basiques de chaines de caractères.

Je caricaturais .. en fait ce que je veux te dire c'est que ça ne sert à rien de tenter de déterminer "le plus rapide", il faut choisir en fonction de ton besoin: parfois moins rapide mais régulier (déterministe) est mieux, parfois encore moins rapide mais résilient est la solution, ... bref, ne te laisse pas guider que par la technique

  • [supprimé]

Ce test n'a aucun rapport avec l'affichage. Je l'ai fait avec Mac OS et Linux. Le but est de vérifier les capacités sur des opérations basiques de chaines de caractères.

Je caricaturais .. en fait ce que je veux te dire c'est que ça ne sert à rien de tenter de déterminer "le plus rapide", il faut choisir en fonction de ton besoin: parfois moins rapide mais régulier (déterministe) est mieux, parfois encore moins rapide mais résilient est la solution, ... bref, ne te laisse pas guider que par la technique

Bonjour,

Mon but était de tenter de mesurer dans un cadre fixe les performances pour ne pas succomber au relativisme absolu.

Il évident que dans certains cas les traitements sont objectivement réalisés plus vites que dans d'autres.

Maintenant dans la pratique les choses ne sont pas forcément ajustées sur ce qui est théoriquement plus performant, d'autant plus que dans mon cas je prends un exemple extrême.

Ceci étant si je dois programmer un outil qui scrute des chaines de manière intensive dans des fichiers ou ailleurs je prendrais plutôt des fonctions du C++ ou du C mais pas de l'Objective C ou du Swift.

Cordialement.

  • [supprimé]

Ce test n'a aucun rapport avec l'affichage. Je l'ai fait avec Mac OS et Linux. Le but est de vérifier les capacités sur des opérations basiques de chaines de caractères.

Je caricaturais .. en fait ce que je veux te dire c'est que ça ne sert à rien de tenter de déterminer "le plus rapide", il faut choisir en fonction de ton besoin: parfois moins rapide mais régulier (déterministe) est mieux, parfois encore moins rapide mais résilient est la solution, ... bref, ne te laisse pas guider que par la technique

Bonjour,

Mon but était de tenter de mesurer dans un cadre fixe les performances pour ne pas succomber au relativisme absolu.

Il évident que dans certains cas les traitements sont objectivement réalisés plus vites que dans d'autres.

Maintenant dans la pratique les choses ne sont pas forcément ajustées sur ce qui est théoriquement plus performant, d'autant plus que dans mon cas je prends un exemple extrême.

Ceci étant si je dois programmer un outil qui scrute des chaines de manière intensive dans des fichiers ou ailleurs je prendrais plutôt des fonctions du C++ ou du C mais pas de l'Objective C ou du Swift.

Cordialement.

Bonjour,

Je viens de voir qu'en intégrant du C++ à Swift on retrouve les performances du C++ sur la tache ainsi programmée en C++, mais bon si à chaque que l'on veut de la performance il faut faire un pont avec C++, le Swift est putôt encombrant. En tout cas les opérations de bas niveaux sur les chaînes de caractères en Swift c'est pas terrible pour ne pas dire pas au point.

Cordialement.

En gros une fois dessaoulé 2 jours après ta question que personne n'a compris t'as trouvé la réponse ... gg l'ami ;)

Je caricaturais .. en fait ce que je veux te dire c'est que ça ne sert à rien de tenter de déterminer "le plus rapide", il faut choisir en fonction de ton besoin: parfois moins rapide mais régulier (déterministe) est mieux, parfois encore moins rapide mais résilient est la solution, ... bref, ne te laisse pas guider que par la technique

Bonjour,

Mon but était de tenter de mesurer dans un cadre fixe les performances pour ne pas succomber au relativisme absolu.

Il évident que dans certains cas les traitements sont objectivement réalisés plus vites que dans d'autres.

Maintenant dans la pratique les choses ne sont pas forcément ajustées sur ce qui est théoriquement plus performant, d'autant plus que dans mon cas je prends un exemple extrême.

Ceci étant si je dois programmer un outil qui scrute des chaines de manière intensive dans des fichiers ou ailleurs je prendrais plutôt des fonctions du C++ ou du C mais pas de l'Objective C ou du Swift.

Cordialement.

Bonjour,

Je viens de voir qu'en intégrant du C++ à Swift on retrouve les performances du C++ sur la tache ainsi programmée en C++, mais bon si à chaque que l'on veut de la performance il faut faire un pont avec C++, le Swift est putôt encombrant. En tout cas les opérations de bas niveaux sur les chaînes de caractères en Swift c'est pas terrible pour ne pas dire pas au point.

Cordialement.j'avais les même résultats que toi quand j'insérais du code assembleur dans mes programmes Pascal... 8-)

  • [supprimé]

En gros une fois dessaoulé 2 jours après ta question que personne n'a compris t'as trouvé la réponse ... gg l'ami ;)

Bonjour,

Non ce n'est pas tout à fait exact. C'est hier soir que j'ai tenté l'intégration du C++ dans Swift. Auparavant je pensais que ce n'était pas possible. Ceci étant cette intégration si elle est possible n'est pas aisée à réaliser.

Et enfin personne n'a pu reprendre mon morceau de code Swift pour lui donner des vitamines.

Cordialement.

  • [supprimé]

Bonjour,

frelon écrit :

J'avais les même résultats que toi quand j'insérais du code assembleur dans mes programmes Pascal...

Oui je me souviens qu'avec MS-DOS c'était payant de coder en Assembleur pour les chaînes de caractères. Ensuite lorsque Delphi est passé au 32 bits ils ont continué à programmer en Assembleur les opérations sur les chaînes.

Dans mon cas avec Swift la fonction en Swift prend plus de 3 minutes alors que le code intégré en C++ ne prend que 5 secondes !!!

Cordialement.

Bonjour,

frelon écrit :

J'avais les même résultats que toi quand j'insérais du code assembleur dans mes programmes Pascal...

Oui je me souviens qu'avec MS-DOS c'était payant de coder en Assembleur pour les chaînes de caractères. Ensuite lorsque Delphi est passé au 32 bits ils ont continué à programmer en Assembleur les opérations sur les chaînes.

Dans mon cas avec Swift la fonction en Swift prend plus de 3 minutes alors que le code intégré en C++ ne prend que 5 secondes !!!

Cordialement.T'in quel con j'ai été d'apprendre à programmer en pascal... :?

Je programmerais en C++ je gagnerais actuellement 20 fois mieux ma vie... :?

La vie est injuste...et pourtant, je sais en faire des putains de trucs avec un ordinateur... :?

Bonjour,

Pour avoir une idée des performances de différents langages de programmation sur une petite épreuve portant sur des chaines de caractères j'ai fait passé un petit test répété un très grand nombre de fois.

(...)

Est-ce que tu pourrais nous mettre les sources en C et C++ stp? Je suis surpris par ton classement.

  • [supprimé]

Bonjour,

Pour avoir une idée des performances de différents langages de programmation sur une petite épreuve portant sur des chaines de caractères j'ai fait passé un petit test répété un très grand nombre de fois.

(...)

Est-ce que tu pourrais nous mettre les sources en C et C++ stp? Je suis surpris par ton classement.

Bonjour,

Pour le C je me sers d'une implémentation que j'ai construite pour les chaines.

Pour le C++ c'est très simple :

using namespace std;

void dotest()

{

string z ( "bArakas mange barakas car boit barakas avec barakas" );

string s1( "ba" );

string s2( "ab") ;

string sb ;

size_t p = 0 ;

//cout << z << endl;

while( 1 )

{

p = z.find( s1 , p );

if( p == string::npos )

break ;

sb = z.substr(p,s1.size()) ;

// cout << "p= " << p << " " << sb << endl ;

p += s1.size();

}

p= 0;

while ( 1 )

{

p = z.find( s1 , p );

if( p == string::npos )

break;

z.replace( p , s1.size(), s2 );

p += s2.size() ;

}

//cout << z << endl;

p= 0;

while ( 1 )

{

p = z.find( s2 , p );

if( p == string::npos )

break;

z.erase( p , s2.size() );

}

//cout << z << endl;

}

Pour le C j'ai extrait la partie nécessaire à ce traitement :

#define _GNU_SOURCE

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/stat.h>

#include <time.h>

#include <ctype.h>

#include <stdarg.h>

#include <assert.h>

#define NOPOS ((size_t) -1)

typedef struct ostring

{

char *g_data;

size_t g_siz;

} ostring;

/************************************************************************************/

char * str_data (ostring * S);

size_t str_size (ostring * S);

char * str_alloc (size_t siz);

void str_init_nb (ostring * S, ...);

void str_clear_nb (ostring * S, ...);

size_t str_find (ostring * S, size_t pos, const char *s, int exact);

void str_clear (ostring * S);

void str_init_with_str (ostring * s, const char *z);

int str_empty (ostring * S);

int str_null (ostring * S);

char * str_substr (ostring * S, ostring * dest, size_t sp, size_t nb);

char * str_delete_at (ostring * S, size_t p, size_t nb);

char * str_insert_at (ostring * S, size_t pos, const char *s);

size_t str_replace_all (ostring * S, size_t p ,const char *oc, const char *nc, int exact);

size_t str_remove_all (ostring * S, size_t p ,const char *z, int exact);

/**********************************************************************/

char *str_data (ostring * S)

{

return S->g_data;

}

size_t str_size (ostring * S)

{

return S->g_siz;

}

char *str_alloc (size_t siz)

{

char *el = 0;

if (siz > 0)

{

el = (char *) malloc (siz * sizeof (char));

assert (el != 0);

}

return el;

}

void str_init_nb (ostring * S, ...)

{

va_list args;

va_start (args, S);

while (S != NULL)

{

S->g_siz = 0;

S->g_data = 0;

S = va_arg (args, ostring *);

}

va_end (args);

}

void str_clear_nb (ostring * S, ...)

{

va_list args;

va_start (args, S);

while (S != NULL)

{

if (S->g_data)

{

free (S->g_data);

S->g_data = 0;

S->g_siz = 0;

}

S = va_arg (args, ostring *);

}

va_end (args);

}

size_t str_find (ostring * S, size_t pos, const char *s, int exact)

{

if (!s)

return NOPOS;

if (pos > S->g_siz)

return NOPOS;

const char* ptr = 0 ;

const char *z = S->g_data + pos;

if( exact )

ptr = strstr( z , s );

if( ! exact )

ptr = strcasestr( z , s );

if (ptr != 0)

return ptr - S->g_data;

return NOPOS;

}

void str_clear (ostring * S)

{

if (S->g_siz > 0)

{

free (S->g_data);

S->g_siz = 0;

S->g_data = 0;

}

}

void str_init_with_str (ostring * s, const char *z)

{

if (z == 0)

z = "";

s->g_siz = strlen (z);

s->g_data = str_alloc (s->g_siz + 1);

strcpy (s->g_data, z);

}

int str_empty (ostring * S)

{

return str_size (S) == 0;

}

int str_null (ostring * S)

{

return (S->g_data == 0) && (S->g_siz == 0);

}

char *str_substr (ostring * S, ostring * dest, size_t sp, size_t nb)

{

assert( 0 == str_null(S) );

if (sp > S->g_siz || str_empty (S))

return S->g_data;

nb = (sp + nb) > str_size (S) ? str_size (S) - sp : nb;

if( nb != dest->g_siz )

{

str_clear(dest);

dest->g_data = str_alloc (nb + 1);

strncpy (&dest->g_data[0], &S->g_data[sp], nb);

*(dest->g_data + nb) = 0;

}

else

{

strncpy (&dest->g_data[0], &S->g_data[sp], nb);

}

dest->g_siz = nb;

return dest->g_data;

}

char *str_delete_at (ostring * S, size_t p, size_t nb)

{

if (S->g_siz == 0 || p >= S->g_siz)

return S->g_data;

nb = (p + nb > S->g_siz) ? S->g_siz - p : nb;

memmove (S->g_data + p, S->g_data + (p + nb), S->g_siz - (p + nb));

S->g_siz -= nb;

*(S->g_data + S->g_siz) = 0;

return S->g_data;

}

char *str_insert_at (ostring * S, size_t pos, const char *s)

{

assert (0 == str_null (S));

size_t osiz = S->g_siz;

size_t sublen = strlen (s);

pos = (pos > osiz) ? osiz : pos;

char *az = str_alloc ((S->g_siz += sublen) + 1);

char *z = az;

char *s1 = S->g_data;

while (pos--)

*z++ = *s1++;

while (*s)

*z++ = *s++;

while (*s1)

*z++ = *s1++;

*z = 0;

free (S->g_data);

S->g_data = az;

return S->g_data;

}

size_t str_replace_all (ostring * S, size_t p ,const char *oc, const char *nc,

int exact)

{

size_t nb = 0;

size_t len = strlen (oc);

size_t n = strlen(nc);

while (NOPOS != (p = str_find (S, p, oc, exact)))

{

str_delete_at (S, p, len);

str_insert_at (S, p, nc);

nb += 1;

p += n ;

}

return nb;

}

size_t str_remove_all (ostring * S, size_t p ,const char *z, int exact)

{

size_t nb = 0;

if (!z)

return nb;

size_t len = strlen (z);

while (NOPOS != (p = str_find (S, p, z, exact)))

{

str_delete_at (S, p, len);

nb += 1;

}

return nb;

}

/*******************************************************************************************/

/* c'est ici le test */

void dotest()

{

ostring z1, z2 ;

str_init_nb (&z1, &z2, NULL);

size_t p = 0 ;

str_init_with_str (&z1, "bArakas mange barakas car boit barakas avec barakas");

//puts (str_data (&z1));

const char * motif = "ba";

size_t len = strlen( motif );

while(1)

{

p = str_find( &z1, p , motif , 1);

if( p == NOPOS )

break ;

char * s = str_substr( &z1, &z2 , p, len );

p += len ;

}

str_replace_all( &z1, 0, "ba" , "ab" , 1 );

//puts (str_data (&z1));

str_remove_all( &z1, 0, "ab" , 1 );

//puts (str_data (&z1));

str_clear_nb (&z1, &z2, NULL);

}

j'ai mesuré sur 9 000 000 répétions.

Cordialement.

Bonjour,

Ce n'est peut-être pas exact de dire que Swift est un nouveau langage. Il dépend à la fois de Objective C et de Clang. Dans certains cas certaines fonctionnalités ne font qu'envelopper des fonctionnalités de Objective C.

Par contre l'écriture est rendue parfois plus simple mais j'ai un doute sur les performances qui pourtant sont vantées par Apple.

Par contre j'ai été surpris de constater que pour mon test, Python qui est interprété a sensiblement les mêmes performances que le Pascal qui est compilé.

Cordialement.

A l'origine le pascal, comme actuellement le java n'était pas compilé dans un code machine mais dans le code d'une machine virtuelle, le p-code, ensuite interprété.

je ne sais pas si python comme java utilise aussi les techniques de compilation à la volée.

  • [supprimé]

Bonjour,

Ce n'est peut-être pas exact de dire que Swift est un nouveau langage. Il dépend à la fois de Objective C et de Clang. Dans certains cas certaines fonctionnalités ne font qu'envelopper des fonctionnalités de Objective C.

Par contre l'écriture est rendue parfois plus simple mais j'ai un doute sur les performances qui pourtant sont vantées par Apple.

Par contre j'ai été surpris de constater que pour mon test, Python qui est interprété a sensiblement les mêmes performances que le Pascal qui est compilé.

Cordialement.

A l'origine le pascal, comme actuellement le java n'était pas compilé dans un code machine mais dans le code d'une machine virtuelle, le p-code, ensuite interprété.

je ne sais pas si python comme java utilise aussi les techniques de compilation à la volée.

Bonjour,

Pour Java il faut une machine virtuelle. Pas pour Python. Je n'ai pas testé en Java je suis un peu rouillé sur le Java. Mais je vais le faire et je pense que la performance sera moins bonne qu'en Python. A voir.

Cordialement.

Bonsour,

Un serpent qui fait la java avec un pingouin.

Cocordialement.

  • [supprimé]

Bonjour,

Je viens de faire le test avec Java. La performance est quasi-identique à celle de Python. Environ 15 .. 16 unités de timer sur 9 000 000 itérations.

Ce genre de test est intéressant pour savoir par exemple la performance d'une fonction comme "faitceci" sans que l'on sache comment "faitceci" fait cela.

Pour Swift la surprise a été de taille. Sauf si quelqu'un trouve un autre moyen plus efficace en Swift.

Cordialement.