Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > SAS Base
SAS Base Forum d'entraide sur SAS base : étape data, procédures non statistiques, procédures non graphiques, SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 19/01/2012, 11h28   #1
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 213
Points : 319
Points : 319
Par défaut Proc FCMP vs Macro SAS : Comparaison temps de calcul

Bonjour,

J'ai créé un certain nombre de fonctions via fcmp, qui auraient également pu être remplacées par des bouts de code sas Macro, et donc je me pose la question des temps de calcul.
Selon votre expérience, est-il avantageux en terme de temps de calcul de mettre ses parties de code complexe lorsqu'elles s'y prêtent sous forme de fonction plutôt que sous forme de code macro ?
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2012, 17h02   #2
Rédacteur
 
Homme Stéphane
Consultant et formateur SAS et Cognos
Inscription : avril 2009
Messages : 1 791
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Consultant et formateur SAS et Cognos
Secteur : Conseil

Informations forums :
Inscription : avril 2009
Messages : 1 791
Points : 4 012
Points : 4 012
Est-il possible de te retourner la question ?
__________________
N'oubliez pas de cliquer sur lorsque votre problème est réglé !

Moteur de recherche dans les papiers SAS
datametric est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/01/2012, 08h24   #3
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 213
Points : 319
Points : 319
Bah j'en sais rien, il faudrait que je fasse des comparaisons de mes fonctions avec du code (sas macro ou pas) inclus directement dans une étape data.

Mes premières impressions c'est que les fonctions programmées via fcmp (pour peu qu'on les optimise...mais c'est la même chose pour tout) semblent "rapides".

Pour autant des papiers à droite et à gauche semblent invoquer un surplus de 50 à 300/400% pour une programmation via "fcmp" vs "sas macro/code normal"

J'essayerais de faire quelques mesures aujourd'hui.

C'est pour ça que je souhaitais avoir un retour d'expérience avec d'autres utilisateurs qui auraient plus ou moins testé , si des préconisations de "bon usage" de la fcmp via macro sas se dégageaient... ?
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/01/2012, 11h43   #4
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 213
Points : 319
Points : 319
voici un premier test, il s'agit d'une fonction pour pallier aux erreurs produites par l'appel de
Code :
input(string,$utf8xw.);
sur des variables codées en UTF8 lorsque la chaine a été altérée (coupure en plein milieu d'un caractère codé en UTF8 et se soldant donc à l'éxecution par une erreur) histoire de récupérer quand même ce qui est récupérable.

J'ai utilisé une table de 5 000 000 de lignes contenant un texte caractère avec des accents

Je soumet les deux codes concurrents , celui avec la proc fcmp

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 
 
 
proc fcmp outlib=sasuser.MyFuncs.ChrFuncs;
FUNCTION PP_UTF8_INV(string$) $400;
length chaine $400 chaine2 $400;
cpt=0;
chaine=string;
longueur=length(chaine);
chaine2='';
l_init=longueur;
do i=1 TO l_init;
lettre=substr(chaine,1,1);l=1;
IF 	longueur>=2
	then do;
    type=indexc(chaine,'C3C2E2C5C6CB'x);
	IF 	type 
	    then do;
		cle=substr(chaine,1,1);
		finale1=substr(chaine,2,1);
			IF 	cle='C3'x
				then	do;
IF indexc(finale1,'808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x)
then do;
lettre=translate(finale1,
'C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF'x,
'808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x);
l=2;
end;
						end;
			else IF cle='C2'x
				 then 	do;
IF indexc(finale1,'818D8F909DA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x)
then do;
lettre=translate(finale1,
'818D8F909DA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x,
'818D8F909DA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x);l=2;
end;
						end;
			else IF 		cle='E2'x
					then	do; 	
							IF 	chaine=:'E280'x 
								then 	do;
										finale2=substr(chaine,3,1);
IF indexc(finale2,'939498999A9C9D9EA0A1A2A6B0B9BA'x)
then do;
lettre=translate(finale2,'969791928293948486879585898B9B'x,'939498999A9C9D9EA0A1A2A6B0B9BA'x);
										l=3;end;
										end;
								else 	do;
										IF chaine=:'E284A2'x then do;lettre='99'x;l=3;end;
										else IF chaine=:'E282AC'x then do;lettre='80'x;l=3;end;
										end;
							end;
			else IF			cle='C5'x
					then	do;
IF indexc(finale1,'9293A0A1B8BDBE'x)
then do;
							lettre=translate(finale1,'8C9C8A9A9F8E9E'x,'9293A0A1B8BDBE'x);
							l=2;end;
							end;
			else IF chaine=:'CB9C'x then do;lettre='98'x;l=2;end;
			else IF chaine=:'CB86'x then do;lettre='88'x;l=2;end;
			else IF chaine=:'C692'x then do;lettre='83'x;l=2;end;
			end;
		end;
IF l=longueur then do;chaine='';end;else do;chaine=substr(chaine,l+1);end;
cpt+1;
substr(chaine2,cpt,1)=lettre;
i=i+(l-1);
longueur=longueur-l;
end;
 
RETURN(chaine2);
ENDSUB;
run;
options cmplib=sasuser.MyFuncs;
 
DATA c; SET b;
length reverse $100;
reverse=pp_utf8_inv(texte1);
run;
et l'autre sous sa forme macro sas

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 
 
%macro pp_utf8_inv(var=);
cpt=0;
chaine=&var.;
longueur=length(chaine);
chaine2='';
l_init=longueur;
do i=1 TO l_init;
lettre=substr(chaine,1,1);l=1;
IF 	longueur>=2
	then do;
    type=indexc(chaine,'C3C2E2C5C6CB'x);
	IF 	type 
	    then do;
		cle=substr(chaine,1,1);
		finale1=substr(chaine,2,1);
			IF 	cle='C3'x
				then	do;
IF indexc(finale1,'808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x)
then do;
lettre=translate(finale1,
'C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF'x,
'808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x);
l=2;
end;
						end;
			else IF cle='C2'x
				 then 	do;
IF indexc(finale1,'818D8F909DA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x)
then do;
lettre=translate(finale1,
'818D8F909DA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x,
'818D8F909DA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'x);l=2;
end;
						end;
			else IF 		cle='E2'x
					then	do; 	
							IF 	chaine=:'E280'x 
								then 	do;
										finale2=substr(chaine,3,1);
IF indexc(finale2,'939498999A9C9D9EA0A1A2A6B0B9BA'x)
then do;
lettre=translate(finale2,'969791928293948486879585898B9B'x,'939498999A9C9D9EA0A1A2A6B0B9BA'x);
										l=3;end;
										end;
								else 	do;
										IF chaine=:'E284A2'x then do;lettre='99'x;l=3;end;
										else IF chaine=:'E282AC'x then do;lettre='80'x;l=3;end;
										end;
							end;
			else IF			cle='C5'x
					then	do;
IF indexc(finale1,'9293A0A1B8BDBE'x)
then do;
							lettre=translate(finale1,'8C9C8A9A9F8E9E'x,'9293A0A1B8BDBE'x);
							l=2;end;
							end;
			else IF chaine=:'CB9C'x then do;lettre='98'x;l=2;end;
			else IF chaine=:'CB86'x then do;lettre='88'x;l=2;end;
			else IF chaine=:'C692'x then do;lettre='83'x;l=2;end;
			end;
		end;
IF l=longueur then do;chaine='';end;else do;chaine=substr(chaine,l+1);end;
cpt+1;
substr(chaine2,cpt,1)=lettre;
i=i+(l-1);
longueur=longueur-l;
end;
reverse=chaine2;
DROP cpt chaine longueur chaine2 l_init cle finale1 l finale2 lettre i type;
%mend;
 
 
DATA d; SET b;
length reverse $100 chaine $100 chaine2 $100;
%pp_utf8_inv(var=texte1);
run;

la log via la fonction

Code :
1
2
3
4
5
6
 
NOTE: There were 5000000 observations READ FROM the DATA SET WORK.B.
NOTE: The DATA SET WORK.C has 5000000 observations AND 3 VARIABLES.
NOTE: DATA statement used (Total process time):
      real time           2:15.56
      cpu time            2:15.15
et celle via la macro

Code :
1
2
3
4
5
6
 
NOTE: There were 5000000 observations READ FROM the DATA SET WORK.B.
NOTE: The DATA SET WORK.D has 5000000 observations AND 3 VARIABLES.
NOTE: DATA statement used (Total process time):
      real time           1:24.28
      cpu time            1:23.92

La version macro est la plus rapide (84 secondes) et la version avec la fonction la plus lente avec un temps supplémentaire d'environ +60% (136 secondes).
L'intérêt au niveau de la programmation de la fonction via proc fcmp, c'est qu'on a pas du tout à gérer dans le programme les dimensionnement des intermédiaires de calcul et la séparation des variables intermédiaires via un drop + les interactions des variables de la macro avec les éventuelles variables de même nom correspondant à celles des données car tout le code est "isolé" dans la fonction.
Une facilité de programmation en plus en plus, mais avec une perte de temps cpu...

C'est un plus lors de la mise au point, mais en cas de traitement lourds et répétés une conversion en macro code de la fonction lorsqu'elle est possible doit donc permettre un gain de temps.
Tout dépend en fait, selon les opérations par rapport au temps total d'execution du programme +60% ou +200% sur une petite étape ce n'est pas forcément la mer à boire...
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 25/01/2012, 22h22   #5
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 213
Points : 319
Points : 319
Question naïve...

La proc proto donne accès à la proc fcmp à des bibliothèques de fonctions C à ce que j'ai compris...

Programmer directement ses fonctions en C puis les appeler via une fonction défini par proc fcmp est-ce plus performant que de "coder" directement la fonction dans une proc fcmp (pour du code plus ou moins complexe, je ne parle pas de faire qu'une addition...) ?

Quelqu'un a t il testé ?

Pour les fonctions C il y a aussi "CALL MODULE"

Idem, quelqu'un a t il testé ?
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 23h40   #6
Rédacteur
 
Homme Stéphane
Consultant et formateur SAS et Cognos
Inscription : avril 2009
Messages : 1 791
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Consultant et formateur SAS et Cognos
Secteur : Conseil

Informations forums :
Inscription : avril 2009
Messages : 1 791
Points : 4 012
Points : 4 012
via la proc PROTO non je n'ai pas testé.

le CALL MODULE oui, c'est un peu instable mais je n'ai jamais fait de test de perf.
__________________
N'oubliez pas de cliquer sur lorsque votre problème est réglé !

Moteur de recherche dans les papiers SAS
datametric est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 20h28   #7
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 213
Points : 319
Points : 319
Petit retour avec mon expérience sur une fonction de similarité.

http://www.developpez.net/forums/d11...imisation-sql/

Le code avec la fonction de similarité programmée via proc fcmp tournait en 15h, après optimisation du programme et ré-intégration du code de la fonction dans le corps même de l'étape DATA le temps n'était plus que d'1h30 (un gain de 10 donc...).

Toujours y regarder à deux fois donc...
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h32.


 
 
 
 
Partenaires

Hébergement Web