Séparer chaine bloque 4D

Bonjour,

C’est juste un constat, 4D ne répond plus jusqu’à la fin de l’exécution de la commande.

Donc, sur une petite chaine pas de pb, ça passe inaperçu, mais sur un texte lourd c’est très gênant !

Dommage

Ha oui, en chargeant la barque de l’exemple de la doc, j’ai la roudlamor.
C’est pas trop optimisé, apparemment, puisqu’on peut mieux faire à pas cher :
<code 4D>
C_TEXTE($vt)
C_COLLECTION($col)
$col:=Créer collection
$vt:=“John;Doe;120 jefferson st.;Riverside;; NJ; 08075”
$vt:=($vt+";")*10000

$ms_l:=Nombre de millisecondes
$col:=Séparer chaine($vt;";")
$t1_l:=Nombre de millisecondes-$ms_l

$ms_l:=Nombre de millisecondes
TABLEAU TEXTE($data_at;0)
Str_explode (->$data_at;$vt;";")
TABLEAU VERS COLLECTION($col;$data_at)
$t2_l:=Nombre de millisecondes-$ms_l
</code 4D>
$t1_l ~ 3700
$t2_l ~ 190
Si je passe le multiplicateur de chaine de 10000 à 50000, ça fait encore plus mal :
$t1_l ~ 483148
$t2_l ~ 701
Mon mac est tout chaud !

Si c’est bloquant ET en plus mal optimisé :-?
Il faudrait que 4D revoie sa copie :twisted:
Bizarre quand même…

Oui, pas eu trop de pb pour m’en passer, mais j’en suis bien triste ! :roll:

Moi pareil.

quand on remarque pesamment qu’on fait mieux qu’une commande 4D avec d’autres commandes 4D, c’est qu’on espère secrètement que ça http://forums.4d.com/Post/FR/15920856/1/15925257#17130775énerve 4D>

Bon Arnaud, tu ouvres une feature pour qu’ils puissent utiliser ton code :lol:

: Arnaud DE MONTARD

TABLEAU TEXTE($data_at;0)
Str_explode (->$data_at;$vt;";")

J’ai remarqué que sur les grosses opérations, il est plus rapide d’exploiter un tableau process qu’un tableau local avec un pointeur, le “dépointage est très gourmand” !!! . J’ai voulu vérifier, les résultats sont très bizarre (la cata pour le pointeur ??:roll:) :

TEST INTERPRETE PUIS EN COMPILÉ :

<code 4D>
C_POINTEUR($point_guil)
$sep_guil:=Caractère(34)
$guillemet:="""
$guillemet:=$sep_guil
$point_guil:=->$sep_guil

$t0:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:=""""
Fin de boucle
$t0:=Nombre de millisecondes-$t0

$t1:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""+"""
Fin de boucle
$t1:=Nombre de millisecondes-$t1

$t2:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""+$sep_guil // +15% en interpréré MAIS 10% plus rapide en compilé !!! (ce n’etais pas le cas avant …attention !
Fin de boucle
$t2:=Nombre de millisecondes-$t2

$t3:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:=$point_guil->+$point_guil-> // +33% en interprété MAIS +1500% en compilé ???
Fin de boucle
$t3:=Nombre de millisecondes-$t3

$t4:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:=Caractère(34)+Caractère(34) // a la ramasse …
Fin de boucle
$t4:=Nombre de millisecondes-$t4

ALERTE(Chaîne($t0)+"\n"+Chaîne($t1)+"\n"+Chaîne($t2)+"\n"+Chaîne($t3)+"\n"+Chaîne($t4))
FIXER TEXTE DANS CONTENEUR("T0 : “+Chaîne($t0)+”\nT1 : “+Chaîne($t1)+”\nT2 : “+Chaîne($t2)+”\nT3 : “+Chaîne($t3)+”\nT4 : "+Chaîne($t4))

</code 4D>

En interprété :
T0 : 2572
T1 : 3931
T2 : 4511
T3 : 5807
T4 : 7005

En compilé :
T0 : 10
T1 : 35
T2 : 36
T3 : 1290 =>>>> dépointage
T4 : 864

j’ai commis une erreur? Ca me semble bizarre un tel écart de vitesse avec le pointeur

Merci Marc, c’est très intéressant !

Du coup je me suis amusé à ajouter quelques cas…

<code 4D>
$t5:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""*2
Fin de boucle
$t5:=Nombre de millisecondes-$t5

Utiliser (Storage)
Storage.test:=Créer objet partagé(“Guillemet”;""")
Fin utiliser
$t6:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""+Storage.test.Guillemet
Fin de boucle
$t6:=Nombre de millisecondes-$t6

C_TEXTE(vGuillemet)
vGuillemet:="""
$t7:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""+vGuillemet
Fin de boucle
$t7:=Nombre de millisecondes-$t7

C_TEXTE(<>Guillemet)
<>Guillemet:="""
$t8:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""+<>Guillemet
Fin de boucle
$t8:=Nombre de millisecondes-$t8

C_OBJET($oGuillemet)
$oGuillemet:=Créer objet(“Guillemet”;""")
$t9:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""+$oGuillemet.Guillemet
Fin de boucle
$t9:=Nombre de millisecondes-$t9

$t10:=Nombre de millisecondes
Boucle ($i;1;2000000)
$guillemet:="""+quote
Fin de boucle
$t10:=Nombre de millisecondes-$t10
</code 4D>

En interprété sur mon MacBook Pro :
T0 : 2190
T1 : 2905
T2 : 3006
T3 : 4007
T4 : 4516
T5 : 2443 -> La multiplication est plus rapide que l’addition…
T6 : 5286
T7 : 2919
T8 : 2910
T9 : 3972 -> Locale mais notation à points, plus long que locale simple en T2
T10: 5021 -> Damned, cout d’une constante en interprété ! :-o

Si je lance 3 process simultanément, en interprété toujours :
(Ils affichent le même CPU en temps réel)
T0 : 5863
T1 : 8348
T2 : 8828
T3 : 12815 -> Ok, ça se confirme pour les pointeurs
T4 : 14201 -> Appeler une fonction coute très cher, normal.
T5 : 8109
T6 : 17193 -> Ouch !
T7 : 9055
T8 : 9324
T9 : 12509 -> :?:
T10: 16986 -> :!:

En compilé :
T0 : 11
T1 : 35
T2 : 34
T3 : 1041 -> Ne pas travailler avec le pointeur est donc une bonne source d’optimisation !
T4 : 965
T5 : 445 -> Ha, en compilé la multiplication perd son avantage, étrange, non ? :expressionless:
T6 : 1706
T7 : 29 -> Donc en compilé c’est pas tant que ça utile de passer par des locales ?..
T8 : 29. Faudrait tester aussi en écriture…
T9 : 826 -> Ça confirme qu’il y a des optimisations à faire !! T2 et T9 devraient êtres plus proches !
T10: 29 -> Ouf ! C’est équivalent à T1, normal

Avec 3 process simultanés :
T0 : 10
T1 : 29
T2 : 29
T3 : 1043
T4 : 983
T5 : 435
T6 : 10176 -> La ça douille, normal, il faut éviter de boucler sur les objets partagés !
T7 : 29
T8 : 30
T9 : 837 -> Au moins, en compilé, c’est stable.
T10: 30

Voila, c’était la récréation du vendredi matin ! :mrgreen:

: Marc LONGO

Ca me semble bizarre un tel écart de vitesse avec le pointeur
Si tu imagines un pointeur comme un “étage de plus à franchir” avant d’accéder à la valeur en mémoire, normal que ça prenne du temps - or ta boucle dépointe 4 millions de fois, par rapport au fait d’assembler deux petites chaines, ça ne me surprend guère. Je trouve au moins aussi remarquable que Caractère(34) appelé 4 millions de fois (T4) coûte à peine moins.

Sinon, pour éviter le “dépointage en masse”, je fais ça, en général :
COPIER TABLEAU (pointeurTableau->;$tableauLocal)
puis je bosse sur $tableauLocal
(pas comme http://forums.4d.com/Post/FR/16119112/1/16119113#16119113ici> :oops:)

: Jacques FADEUILHE

T9 : 826 -> Ça confirme qu’il y a des optimisations à faire !! T2 et
T9 devraient êtres plus proches !
J’ai l’impression qu’un objet 4D, fondamentalement, est une “évolution” du pointeur
• dans les conférences et la doc on nous dit qu’un objet est une référence (“La commande Creer objet crée un objet vide ou pré-rempli et retourne sa référence”), un pointeur est aussi décrit comme une référence (“Vous pouvez utiliser des pointeurs pour référencer des tables, des champs, des variables, des tableaux et des éléments de tableaux.”)
• comme le pointeur, l’objet est un paramètre qu’une méthode peut modifier :
maMethode(->variable) —> variable modifiée en sortie
maMethode(objet) —> objet modifié en sortie
• je crois me rappeler qu’Olivier avait dit que pointer un objet était un peu s’infliger une double peine
• « La notation objet pour les pointeurs est semblable à la notation objet standard, à la seule différence que le symbole “point” doit être omis. » : ça ressemble étrangement à un pointeur qu’on aurait doté de propriétés

Si je tente de vérifier le coût d’accès en adaptant vos tests :
<code 4D>
TRACE

C_ENTIER LONG($i_l)
C_POINTEUR($point_guil)
$sep_guil:=Caractère(34)
$guillemet:="""
$guillemet:=$sep_guil
$point_guil:=->$sep_guil
$end_l:=Choisir(Mode compilé;2000000;200000)
TABLEAU ENTIER LONG($time_al;0)

$ms_l:=Nombre de millisecondes
Boucle ($i_l;1;$end_l)
$guillemet:="""+"""
Fin de boucle
AJOUTER À TABLEAU($time_al;Nombre de millisecondes-$ms_l)

$ms_l:=Nombre de millisecondes
Boucle ($i_l;1;$end_l)
$guillemet:=$point_guil->+$point_guil-> //2 dépointages
Fin de boucle
AJOUTER À TABLEAU($time_al;Nombre de millisecondes-$ms_l)

C_OBJET($oGuillemet)
$oGuillemet:=Créer objet(“quote”;""")
$ms_l:=Nombre de millisecondes
Boucle ($i_l;1;$end_l)
$guillemet:=$oGuillemet.quote+$oGuillemet.quote //2 lectures de propriété
Fin de boucle
AJOUTER À TABLEAU($time_al;Nombre de millisecondes-$ms_l)

C_POINTEUR($obj_p)
$obj_p:=->$oGuillemet
$ms_l:=Nombre de millisecondes
Boucle ($i_l;1;$end_l)
$guillemet:=$obj_p->quote+$obj_p->quote //2 dépointages + lecture de propriété
Fin de boucle
AJOUTER À TABLEAU($time_al;Nombre de millisecondes-$ms_l)

//++++++++++++++++++++++++
$alerte_t:=""
Boucle ($i_l;1;Taille tableau($time_al))
$alerte_t:=$alerte_t+Chaîne($i_l)+" = “+Chaîne($time_al{$i_l})+”\r"
Fin de boucle
ALERTE($alerte_t)
</code 4D>
1 = 34
2 = 1172
3 = 1163
4 = 2580

• 2 comparé à 3 : ça prend le même temps de lire une propriété d’objet que de lire une valeur pointée (test répété plusieurs fois, je n’ai pas trouvé de différence significative)
• 4 comparé à 2/3 : lire une propriété dans un objet pointé est effectivement une double peine (et même un peu plus)

Tout ça pour dire qu’un objet ajoute aussi un étage et que cet étage ressemble beaucoup à celui du pointeur.

Sujet interessant pour ceux qui comme moi font parfois de gros traitements réguliers.

Et il va falloir que je revois pas mal de méthodes du coup … car il y a des écarts “VERTIGINEUX” de vitesse que je ne soupçonnais pas.:roll:

Pour continuer dans la tristesse…

Soit une collection $cIDF_Mots de 113 502 mots

Soit une autre collection $cTabMots de 712 mots

Je me retrouve avec le serveur et les clients gelés en mode arc en ciel pendant…

<code 4D>

$cPos:=$cIDF_Mots.indices(“m IN :1”;$cTabMots) // 39s

$cPos:=$cIDF_Mots.query(“m IN :1”;$cTabMots) // 38s

$cPos:=Storage.ADV.IDF_Mots.query(“m IN :1”;$cTabMots) // 39s

</code 4D>

Donc pas utilisable, car en plus je peux avoir plusieurs clients qui déclenchent ce type de traitement en même temps !

:cry:

Que ça prenne du temps ne me pose pas (trop) de problème, ce qui n’est pas possible c’est que le serveur soit en mode “ne répond plus” alors que j’ai 20 process web qui font des demandes !

Et à l’argument de “il faut le faire dans un process préemptif”, je dirais que oui, mais non, aucune commande ne doit bloquer l’exécution, jamais !

Jacques