<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CV SAS MVS Unix Windows Ingénieur Systeme Décisionnel SAS Consultant, Développeur, Formateur, CDI, CDD, Freelance &#187; Optimisation SAS</title>
	<atom:link href="http://cv-sas-mvs-unix-windows.001ordi.com/category/optimisation-sas/feed" rel="self" type="application/rss+xml" />
	<link>http://cv-sas-mvs-unix-windows.001ordi.com</link>
	<description>CV SAS : Compétences autour des produits SAS</description>
	<lastBuildDate>Tue, 06 Dec 2011 14:43:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>SAS Optimisation : Data Merge contre Hashing</title>
		<link>http://cv-sas-mvs-unix-windows.001ordi.com/optimisation-sas/00081/sas-data-merge_contre-hashing.html</link>
		<comments>http://cv-sas-mvs-unix-windows.001ordi.com/optimisation-sas/00081/sas-data-merge_contre-hashing.html#comments</comments>
		<pubDate>Wed, 05 Aug 2009 15:56:17 +0000</pubDate>
		<dc:creator>P-MAUBERT CV SAS</dc:creator>
				<category><![CDATA[Optimisation SAS]]></category>

		<guid isPermaLink="false">http://cv-sas-mvs-unix-windows.001ordi.com/?p=81</guid>
		<description><![CDATA[Comparaison entre Data Merge et Hash (Hashing) Présentation. Bien souvent en SAS nous sommes amené à traiter des volumes d&#8217;information très important, aussi il est nécessaire de pouvoir optimiser le code de nos programmes SAS, afin de diminuer les temps de traitement. Dans cette article nous allons nous pencher sur une technique de traitement des [...]]]></description>
			<content:encoded><![CDATA[<h1>Comparaison entre Data Merge et Hash (Hashing)</h1>
<p><strong>Présentation.</strong></p>
<p>Bien souvent en SAS nous sommes amené à traiter des volumes d&#8217;information très important, aussi il est nécessaire de pouvoir optimiser le code de nos programmes SAS, afin de diminuer les temps de traitement.</p>
<p>Dans cette article nous allons nous pencher sur une technique de traitement des données SAS optimisant de manière importante la résolution de la problématique &laquo;&nbsp;Performance&nbsp;&raquo; lors de la fusion de données SAS</p>
<h2><strong>Le Code HASH</strong></h2>
<p>Le <strong>code HASH</strong> ou le souvent nommé « <strong>hashing </strong>» est disponible depuis la version SAS®9. Il nous fournit  des méthodes très rapides et plus efficaces pour stocker, rechercher et plus généralement manipuler des données dans des tables basées sur des clés d’identification.</p>
<h2>Fonctionnement, démarche avec le <strong>Code Hash</strong></h2>
<p>Pour un néophyte, <strong>le code hash de SAS</strong>, apparait comme étant plus compliqué à assimiler que le langage SAS  base. Toutefois cela n&#8217;est pas très vrai et quand bien même ! Le jeu en vaut la chandelle.</p>
<p><strong>Le code Hash</strong> est un code objet permettant de gérer une table en mémoire, avec comme toute autre table SAS, des lignes et des colonnes (variables, observations).</p>
<p><span id="more-81"></span></p>
<p><strong>La syntaxe de ces commandes est  la suivante</strong> : Nom_objet_Hash.Nom_commande(&lt;paramètre&gt;);</p>
<h3>I Créer une table en mémoire (objet hash)</h3>
<p>La commande .Declare(), permet de faire cela :</p>
<p><strong>Declare hash ma_table_hash () ;</strong></p>
<h3><strong>II Ensuite, définir la structure de la table</strong></h3>
<p>Définition des variables : clé et données en utilisant les commandes <strong>DefineKey</strong>() et <strong>DefineData</strong>()<strong>.</strong></p>
<p>* Définir la taille des variables de la table en mémoire;<br />
** Afin d&#8217;optimiser, vous pouvez vous reporter dans l&#8217;aide de SAS : Using SAS software in your operating environment<br />
** Using SAS in Windows<br />
** Length and precision of variables<br />
** Numeric variables</p>
<p>Vous y apprendrez qu&#8217;il est souvent inutile de mettre une longueur de 8 pour des variables numériques.;</p>
<p><strong>Length clevar var1-var4 8 ;</strong><br />
<strong>array var(4);</strong></p>
<p>* Définir la variable clé;<br />
<strong>rc = ma_table_hash.DefineKey (“clevar”);</strong></p>
<p>* Définir les autres variables;</p>
<p><strong>rc = ma_table_hash.DefineData (“var1”, “var2”, “var3”, “var4”);</strong></p>
<p>*Ecriture de la structure de la table;<br />
<strong>rc = ma_table_hash.DefineDone ();</strong></p>
<p>Ensuite il faut remplir cette table.</p>
<p>Puis on initialise  les observations de la table en mémoire à partir de la tablun. Les observations sont lues et ajoutées une par une dans l’objet hash grâce à la commande .add().</p>
<p><strong>do until (fin_tableun) ;<br />
set tableun (keep=clevar var1-var4) end =fin_tableun;<br />
rc = ma_table_hash.add() ;<br />
end ;</strong></p>
<p>Accéder aux données de la table</p>
<p>La variable clevar est lue observation par observation à partir de la tabledeux.</p>
<p>Ensuite avec la commande .find(), on recherche dans la table (mémoire) si celle-ci contient un observation correspondante à la valeur recherchée présente dans la variable clevar et si oui, alors les valeurs correspondantes sont écrites dans le PDV (Program Data Vector).</p>
<p><strong>do until (fin_tabledeux) ;<br />
set tabledeux end =fin_tabledeux;<br />
do i=lbound(var) to hbound(var);<br />
var(i) = .;<br />
end;<br />
rc = </strong><strong>ma_table_hash</strong><strong>.find() ;<br />
output ;<br />
end ;<br />
run ;</strong></p>
<p><strong>Attention </strong>l&#8217;instruction <strong>OUTPUT </strong>copie le contenu du <strong>PDV </strong>dans une observation de la table en sortie, mais elle <strong>ne vide pas</strong> le contenu des variables du PDV, il est donc essentiel de bien penser à <strong>initialiser à manquant les variables du PDV</strong>.</p>
<p>Dernier point sur la partie téhorique, le calcul de l&#8217;espace mémoire nécessaire à une opération de hashing.</p>
<p>Taille de l’objet hash =           <img src="http://www.sas.com/offices/europe/france/services/support/articles/images/formule.gif" alt="" width="335" height="50" /></p>
<p>Bien, nous pouvons maintenant passer à la partie technique de la démonstration, voici ci-après, dans l&#8217;ordre le code SAS d&#8217;un exemple de programme SAS utilisant la technique traditionnelle DATA SORT et MERGE et enfin le <strong>HASHING </strong>&#8230;</p>
<p>Malgré l&#8217;amélioration très significative, facteur 3 du Code Hash, nous verrons qu&#8217;il est encore possible de <strong>diviser par deux</strong> cet honorable résultat.</p>
<p>Tout de suite après ce programme, vous trouverez le compte rendu d&#8217;exécution de ce programme, soit le journal SAS ou encore la LOG SAS.</p>
<p><strong>/*<br />
Titre: Comparaison.sas DATA MERGE et DATA HASH<br />
Date:  05/08/2009<br />
Auteur Pascal Maubert issue d&#8217;un travail de base de<br />
Pascal Lemetayer.</strong></p>
<p><strong>BUT    Le but de ce programme est démontrer que dans<br />
certains cas des techniques comme le Hashing<br />
peuvent optimiser les performances d&#8217;un traitement.</strong></p>
<p><strong>D&#8217;autres éléments d&#8217;optimisations seront exposés.</strong></p>
<p><strong>Machine Windows Vista AMD Phenom 9550 4 coeurs<br />
à 2.20 Ghz SAS 9.10<br />
*/</strong></p>
<p><strong>* Offre des informations supplémentaires sur une éxecution de code SAS;<br />
options fullstimer;</strong></p>
<p><strong>/*Création des tables de données pour le test */</strong></p>
<p><strong>%let grand_obs = 500000;</strong></p>
<p><strong>data petit ( keep = clevar petit: )<br />
grand ( keep = clevar grand: )<br />
;<br />
array keys(1:500000) $1 _temporary_;<br />
length clevar 8;<br />
array petitvar [20]; retain petitvar 12;<br />
array grandvar [682]; retain grandvar  55;<br />
do _i_ = 1 to &amp;grand_obs ;<br />
clevar = ceil (ranuni(1) * &amp;grand_obs);<br />
if keys(clevar) = &#8216; &#8216; then do;<br />
output grand;<br />
if ranuni(1) &lt; 1/5 then output petit;<br />
keys(clevar) = &#8216;X&#8217;;<br />
end;<br />
end;<br />
run;</strong></p>
<p><strong>/* METHODE 1 SORT, DATA MERGE*/</strong></p>
<p><strong>proc sort data=petit; by clevar;<br />
run;</strong></p>
<p><strong>proc sort data=grand; by clevar;<br />
run;</strong></p>
<p><strong>data match_merge;<br />
merge grand (in=a)<br />
petit (in=b);<br />
by clevar;<br />
if a;<br />
run;</strong></p>
<p><strong>/* METHODE 2 HASHING */</strong></p>
<p><strong>data hash_merge (drop=rc i);</strong></p>
<p><strong>/* Création de la table en mémoire */<br />
declare hash h_petit ();</strong></p>
<p><strong>/* Maintenant la structure */<br />
length clevar petitvar1-petitvar20 8;<br />
array petitvar(20);<br />
rc = h_petit.DefineKey  ( &laquo;&nbsp;clevar&nbsp;&raquo; );<br />
rc = h_petit.DefineData ( &laquo;&nbsp;petitvar1&#8243;,&nbsp;&raquo;petitvar2&#8243;,&nbsp;&raquo;petitvar3&#8243;,&nbsp;&raquo;petitvar4&#8243;,<br />
&laquo;&nbsp;petitvar5&#8243;,&nbsp;&raquo;petitvar6&#8243;,&nbsp;&raquo;petitvar7&#8243;,&nbsp;&raquo;petitvar8&#8243;,<br />
&laquo;&nbsp;petitvar9&#8243;,&nbsp;&raquo;petitvar10&#8243;,&nbsp;&raquo;petitvar11&#8243;,&nbsp;&raquo;petitvar12&#8243;,<br />
&laquo;&nbsp;petitvar13&#8243;,&nbsp;&raquo;petitvar14&#8243;,&nbsp;&raquo;petitvar15&#8243;,&nbsp;&raquo;petitvar16&#8243;,<br />
&laquo;&nbsp;petitvar17&#8243;,&nbsp;&raquo;petitvar18&#8243;,&nbsp;&raquo;petitvar19&#8243;,&nbsp;&raquo;petitvar20&#8243; );<br />
rc = h_petit.DefineDone ();</strong></p>
<p><strong>/* Chargement de la table mémoire avec la table petit  */<br />
do until ( fin_petit );<br />
set petit end = fin_petit;<br />
rc = h_petit.add ();<br />
end;</strong></p>
<p><strong>/* Création de la table fusionnée */<br />
do until ( fin_grand );<br />
set grand end = fin_grand;<br />
/*Initialisation des variables manquantes */<br />
do i=lbound(petitvar) to hbound(petitvar);<br />
petitvar(i) = .;<br />
end;<br />
rc = h_petit.find ();<br />
output;<br />
end;<br />
run;</strong></p>
<p><strong>/* Pour aller plus loin et encore optimiser plus</strong></p>
<p><strong>Notez qu&#8217;il n&#8217;est pas possible de se passer<br />
des étapes de tri, car l&#8217;option &laquo;&nbsp;notsorted&nbsp;&raquo;<br />
ne peut être utilisée pour les instructions<br />
MERGE ou UPDATE</strong></p>
<p><strong>Reprise du test, mais cette fois en utilisant<br />
une optimisation supplémentaires l&#8217;option compress.<br />
Il en existe deux ayant pour but d&#8217;optimiser la<br />
compression de tables contenant essentiellement<br />
des variables en caractères et une seconde pour des<br />
variables numériques.</strong></p>
<p><strong>O P T I M I S A T I O N  -  T U N I N G<br />
*/</strong></p>
<p><strong>options bufno=8 bufsize=32768 fullstimer compress=binary;</strong></p>
<p><strong>/* nous pourrions également diminuer la longueur de la variables clevar à 4, voir<br />
&laquo;&nbsp;Significant Digits and grandst Integer by Length for SAS Variables under Windows&nbsp;&raquo;, Z/OS etc&#8230;<br />
sous windows 4 permet jusqu&#8217;à 2**21 soit 2,097,152, peu utile avec l&#8217;option compress */</strong></p>
<p><strong>/*Création des tables de données de test*/</strong></p>
<p><strong>%let grand_obs = 500000;</strong></p>
<p><strong>data petit ( keep = clevar petit: )<br />
grand ( keep = clevar grand: )<br />
;<br />
array keys(1:500000) $1 _temporary_;<br />
length clevar 8;<br />
array petitvar [20]; retain petitvar 12;<br />
array grandvar [682]; retain grandvar  55;<br />
do _i_ = 1 to &amp;grand_obs ;<br />
clevar = ceil (ranuni(1) * &amp;grand_obs);<br />
if keys(clevar) = &#8216; &#8216; then do;<br />
output grand;<br />
if ranuni(1) &lt; 1/5 then output petit;<br />
keys(clevar) = &#8216;X&#8217;;<br />
end;<br />
end;<br />
run;</strong></p>
<p><strong>/* METHODE 1 SORT, DATA MERGE*/</strong></p>
<p><strong>proc sort data=petit; by clevar;<br />
run;</strong></p>
<p><strong>proc sort data=grand; by clevar;<br />
run;</strong></p>
<p><strong>data match_merge;<br />
merge grand (in=a)<br />
petit (in=b);<br />
by clevar;<br />
if a;<br />
run;</strong></p>
<p><strong>/* METHODE 2 HASHING */</strong></p>
<p><strong>data hash_merge (drop=rc i);</strong></p>
<p><strong>/* Création de la table en mémoire */<br />
declare hash h_petit ();</strong></p>
<p><strong>/* Maintenant la structure */</strong></p>
<p><strong>length clevar petitvar1-petitvar20 8;<br />
array petitvar(20);<br />
rc = h_petit.DefineKey  ( &laquo;&nbsp;clevar&nbsp;&raquo; );<br />
rc = h_petit.DefineData ( &laquo;&nbsp;petitvar1&#8243;,&nbsp;&raquo;petitvar2&#8243;,&nbsp;&raquo;petitvar3&#8243;,&nbsp;&raquo;petitvar4&#8243;,<br />
&laquo;&nbsp;petitvar5&#8243;,&nbsp;&raquo;petitvar6&#8243;,&nbsp;&raquo;petitvar7&#8243;,&nbsp;&raquo;petitvar8&#8243;,<br />
&laquo;&nbsp;petitvar9&#8243;,&nbsp;&raquo;petitvar10&#8243;,&nbsp;&raquo;petitvar11&#8243;,&nbsp;&raquo;petitvar12&#8243;,<br />
&laquo;&nbsp;petitvar13&#8243;,&nbsp;&raquo;petitvar14&#8243;,&nbsp;&raquo;petitvar15&#8243;,&nbsp;&raquo;petitvar16&#8243;,<br />
&laquo;&nbsp;petitvar17&#8243;,&nbsp;&raquo;petitvar18&#8243;,&nbsp;&raquo;petitvar19&#8243;,&nbsp;&raquo;petitvar20&#8243; );<br />
rc = h_petit.DefineDone ();</strong></p>
<p><strong>/* Chargement de la table mémoire avec la table petit  */</strong></p>
<p><strong>do until ( fin_petit );<br />
set petit end = fin_petit;<br />
rc = h_petit.add ();<br />
end;</strong></p>
<p><strong>/* Création de la table fusionnée */<br />
do until ( fin_grand );<br />
set grand end = fin_grand;<br />
/*Initialisation des variables manquantes */<br />
do i=lbound(petitvar) to hbound(petitvar);<br />
petitvar(i) = .;<br />
end;<br />
rc = h_petit.find ();<br />
output;<br />
end;<br />
run;</strong></p>
<p><strong>LA LOG SAS</strong></p>
<p>Note: Copyright (c) 2002 by SAS Institute Inc., Cary, NC, USA.<br />
Note: SAS (r) Proprietary Software Version 9.00 (TS M0)<br />
Note: La session est exécutée sur la plate-forme WIN_PRO .</p>
<p>Note: Initialisation de SAS used:<br />
temps réel                   0.59 secondes<br />
temps processeur             0.54 secondes</p>
<p>1    /*<br />
2      Titre: Comparaison.sas DATA MERGE et DATA HASH<br />
3      Date:  05/08/2009<br />
4      Auteur Pascal Maubert issue d&#8217;un travail de base de<br />
5             Pascal Lemetayer.<br />
6<br />
7      BUT    Le but de ce programme est démontrer que dans<br />
8             certains cas des techniques comme le Hashing<br />
9             peuvent optimiser les performances d&#8217;un traitement.<br />
10<br />
11            D&#8217;autres éléments d&#8217;optimisations seront exposés.<br />
12<br />
13            Machine Windows Vista AMD Phenom 9550 4 coeurs<br />
14            à 2.20 Ghz SAS 9.10<br />
15   */<br />
16<br />
17   * Offre des informations supplémentaires sur une éxecution de code SAS;<br />
18   options fullstimer;<br />
19<br />
20   /*Création des tables de données pour le test */<br />
21<br />
22   %let grand_obs = 500000;<br />
23<br />
24   data petit ( keep = clevar petit: )<br />
25        grand ( keep = clevar grand: )<br />
26        ;<br />
27      array keys(1:500000) $1 _temporary_;<br />
28      length clevar 8;<br />
29      array petitvar [20]; retain petitvar 12;<br />
30      array grandvar [682]; retain grandvar  55;<br />
31      do _i_ = 1 to &amp;grand_obs ;<br />
32         clevar = ceil (ranuni(1) * &amp;grand_obs);<br />
33         if keys(clevar) = &#8216; &#8216; then do;<br />
34            output grand;<br />
35            if ranuni(1) &lt; 1/5 then output petit;<br />
36        keys(clevar) = &#8216;X&#8217;;<br />
37       end;<br />
38      end;<br />
39   run;</p>
<p>Note: La table WORK.PETIT a 63406 observations et 21 variables.<br />
Note: La table WORK.GRAND a 315975 observations et 683 variables.<br />
Note: L&#8217;étape DATA used (Total process time):<br />
temps réel                   18.17 secondes<br />
temps processeur utilisateur 0.84 secondes<br />
temps processeur système     3.55 secondes<br />
Mémoire                            4785k</p>
<p>40<br />
41<br />
42   /* METHODE 1 SORT, DATA MERGE*/<br />
43<br />
44   proc sort data=petit; by clevar;<br />
45   run;</p>
<p>Note:  63406 observations copiées de la table WORK.PETIT.<br />
Note: La table WORK.PETIT a 63406 observations et 21 variables.<br />
Note: La procédure SORT used (Total process time):<br />
temps réel                   0.09 secondes<br />
temps processeur utilisateur 0.07 secondes<br />
temps processeur système     0.07 secondes<br />
Mémoire                            89k</p>
<p>46<br />
47   proc sort data=grand; by clevar;<br />
48   run;</p>
<p>Note:  315975 observations copiées de la table WORK.GRAND.<br />
Note: La table WORK.GRAND a 315975 observations et 683 variables.<br />
Note: La procédure SORT used (Total process time):<br />
temps réel                   1:20.49<br />
temps processeur utilisateur 5.46 secondes<br />
temps processeur système     13.16 secondes<br />
Mémoire                            223k</p>
<p>49<br />
50   data match_merge;<br />
51      merge grand (in=a)<br />
52            petit (in=b);<br />
53      by clevar;<br />
54      if a;<br />
55   run;</p>
<p>Note:  315975 observations copiées de la table WORK.GRAND.<br />
Note:  63406 observations copiées de la table WORK.PETIT.<br />
Note: La table WORK.MATCH_MERGE a 315975 observations et 703 variables.<br />
Note: L&#8217;étape DATA used (Total process time):<br />
temps réel                   39.93 secondes<br />
temps processeur utilisateur 1.88 secondes<br />
temps processeur système     6.44 secondes<br />
Mémoire                            532k</p>
<p>56<br />
57   /* METHODE 2 HASHING */<br />
58<br />
59   data hash_merge (drop=rc i);<br />
60<br />
61      /* Création de la table en mémoire */<br />
62      declare hash h_petit ();<br />
63<br />
64      /* Maintenant la structure */<br />
65      length clevar petitvar1-petitvar20 8;<br />
66      array petitvar(20);<br />
67      rc = h_petit.DefineKey  ( &laquo;&nbsp;clevar&nbsp;&raquo; );<br />
68      rc = h_petit.DefineData ( &laquo;&nbsp;petitvar1&#8243;,&nbsp;&raquo;petitvar2&#8243;,&nbsp;&raquo;petitvar3&#8243;,&nbsp;&raquo;petitvar4&#8243;,</p>
<p>69                                &laquo;&nbsp;petitvar5&#8243;,&nbsp;&raquo;petitvar6&#8243;,&nbsp;&raquo;petitvar7&#8243;,&nbsp;&raquo;petitvar8&#8243;,</p>
<p>70                                &laquo;&nbsp;petitvar9&#8243;,&nbsp;&raquo;petitvar10&#8243;,&nbsp;&raquo;petitvar11&#8243;,&nbsp;&raquo;petitvar12&#8243;,</p>
<p>71                                &laquo;&nbsp;petitvar13&#8243;,&nbsp;&raquo;petitvar14&#8243;,&nbsp;&raquo;petitvar15&#8243;,&nbsp;&raquo;petitvar16&#8243;,</p>
<p>72                                &laquo;&nbsp;petitvar17&#8243;,&nbsp;&raquo;petitvar18&#8243;,&nbsp;&raquo;petitvar19&#8243;,&nbsp;&raquo;petitvar20&#8243; );</p>
<p>73      rc = h_petit.DefineDone ();<br />
74<br />
75      /* Chargement de la table mémoire avec la table petit  */<br />
76      do until ( fin_petit );<br />
77         set petit end = fin_petit;<br />
78         rc = h_petit.add ();<br />
79      end;<br />
80<br />
81      /* Création de la table fusionnée */<br />
82      do until ( fin_grand );<br />
83         set grand end = fin_grand;<br />
84         /*Initialisation des variables manquantes */<br />
85         do i=lbound(petitvar) to hbound(petitvar);<br />
86            petitvar(i) = .;<br />
87         end;<br />
88         rc = h_petit.find ();<br />
89         output;<br />
90      end;<br />
91   run;</p>
<p>Note:  63406 observations copiées de la table WORK.PETIT.<br />
Note:  315975 observations copiées de la table WORK.GRAND.<br />
Note: La table WORK.HASH_MERGE a 315975 observations et 703 variables.<br />
Note: L&#8217;étape DATA used (Total process time):<br />
temps réel                   39.67 secondes<br />
temps processeur utilisateur 2.04 secondes<br />
temps processeur système     5.88 secondes<br />
Mémoire                            420k</p>
<p>92<br />
93<br />
94   /* Pour aller plus loin et encore optimiser plus<br />
95<br />
96      Notez qu&#8217;il n&#8217;est pas possible de se passer<br />
97      des étapes de tri, car l&#8217;option &laquo;&nbsp;notsorted&nbsp;&raquo;<br />
98      ne peut être utilisée pour les instructions<br />
99      MERGE ou UPDATE<br />
100<br />
101     Reprise du test, mais cette fois en utilisant<br />
102     une optimisation supplémentaires l&#8217;option compress.<br />
103     Il en existe deux ayant pour but d&#8217;optimiser la<br />
104     compression de tables contenant essentiellement<br />
105     des variables en caractères et une seconde pour des<br />
106     variables numériques.<br />
107<br />
108     O P T I M I S A T I O N  -  T U N I N G<br />
109  */<br />
110<br />
111  options bufno=8 bufsize=32768 fullstimer compress=binary;<br />
112<br />
113  /* nous pourrions également diminuer la longueur de la variables clevar à 4, voir</p>
<p>114  &laquo;&nbsp;Significant Digits and grandst Integer by Length for SAS Variables under Windows&nbsp;&raquo;, Z/OS etc&#8230;</p>
<p>115  sous windows 4 permet jusqu&#8217;à 2**21 soit 2,097,152, peu utile avec l&#8217;option compress */</p>
<p>116<br />
117  /*Création des tables de données de test*/<br />
118<br />
119  %let grand_obs = 500000;<br />
120<br />
121  data petit ( keep = clevar petit: )<br />
122       grand ( keep = clevar grand: )<br />
123       ;<br />
124     array keys(1:500000) $1 _temporary_;<br />
125     length clevar 8;<br />
126     array petitvar [20]; retain petitvar 12;<br />
127     array grandvar [682]; retain grandvar  55;<br />
128     do _i_ = 1 to &amp;grand_obs ;<br />
129        clevar = ceil (ranuni(1) * &amp;grand_obs);<br />
130        if keys(clevar) = &#8216; &#8216; then do;<br />
131           output grand;<br />
132           if ranuni(1) &lt; 1/5 then output petit;<br />
133       keys(clevar) = &#8216;X&#8217;;<br />
134      end;<br />
135     end;<br />
136  run;</p>
<p>Note: La table WORK.PETIT a 63406 observations et 21 variables.<br />
Note: La compression de la table WORK.PETIT a réduit la taille de 60.86 pourcent.<br />
Compression de 128 pages; la décompression nécessiterait 327 pages.<br />
Note: La table WORK.GRAND a 315975 observations et 683 variables.<br />
Note: La compression de la table WORK.GRAND a réduit la taille de 77.26 pourcent.<br />
Compression de 14371 pages; la décompression nécessiterait 63197 pages.<br />
Note: L&#8217;étape DATA used (Total process time):<br />
temps réel                   15.08 secondes<br />
temps processeur utilisateur 13.36 secondes<br />
temps processeur système     0.96 secondes<br />
Mémoire                            4817k</p>
<p>137<br />
138  /* METHODE 1 SORT, DATA MERGE*/<br />
139<br />
140  proc sort data=petit; by clevar;<br />
141  run;</p>
<p>Note:  63406 observations copiées de la table WORK.PETIT.<br />
Note: La table WORK.PETIT a 63406 observations et 21 variables.<br />
Note: La compression de la table WORK.PETIT a réduit la taille de 60.86 pourcent.<br />
Compression de 128 pages; la décompression nécessiterait 327 pages.<br />
Note: La procédure SORT used (Total process time):<br />
temps réel                   0.29 secondes<br />
temps processeur utilisateur 0.24 secondes<br />
temps processeur système     0.06 secondes<br />
Mémoire                            89k</p>
<p>142<br />
143  proc sort data=grand; by clevar;<br />
144  run;</p>
<p>Note:  315975 observations copiées de la table WORK.GRAND.<br />
Note: La table WORK.GRAND a 315975 observations et 683 variables.<br />
Note: La compression de la table WORK.GRAND a réduit la taille de 77.26 pourcent.<br />
Compression de 14371 pages; la décompression nécessiterait 63197 pages.<br />
Note: La procédure SORT used (Total process time):<br />
temps réel                   39.03 secondes<br />
temps processeur utilisateur 19.45 secondes<br />
temps processeur système     8.14 secondes<br />
Mémoire                            261k</p>
<p>145<br />
146  data match_merge;<br />
147     merge grand (in=a)<br />
148           petit (in=b);<br />
149     by clevar;<br />
150     if a;<br />
151  run;</p>
<p>Note:  315975 observations copiées de la table WORK.GRAND.<br />
Note:  63406 observations copiées de la table WORK.PETIT.<br />
Note: La table WORK.MATCH_MERGE a 315975 observations et 703 variables.<br />
Note: La compression de la table WORK.MATCH_MERGE a réduit la taille de 76.18 pourcent.<br />
Compression de 15055 pages; la décompression nécessiterait 63198 pages.<br />
Note: L&#8217;étape DATA used (Total process time):<br />
temps réel                   18.89 secondes<br />
temps processeur utilisateur 16.66 secondes<br />
temps processeur système     1.15 secondes<br />
Mémoire                            546k</p>
<p>152<br />
153  /* METHODE 2 HASHING */<br />
154<br />
155  data hash_merge (drop=rc i);<br />
156<br />
157     /* Création de la table en mémoire */<br />
158     declare hash h_petit ();<br />
159<br />
160     /* Maintenant la structure */<br />
161<br />
162     length clevar petitvar1-petitvar20 8;<br />
163     array petitvar(20);<br />
164     rc = h_petit.DefineKey  ( &laquo;&nbsp;clevar&nbsp;&raquo; );<br />
165     rc = h_petit.DefineData ( &laquo;&nbsp;petitvar1&#8243;,&nbsp;&raquo;petitvar2&#8243;,&nbsp;&raquo;petitvar3&#8243;,&nbsp;&raquo;petitvar4&#8243;,</p>
<p>166                               &laquo;&nbsp;petitvar5&#8243;,&nbsp;&raquo;petitvar6&#8243;,&nbsp;&raquo;petitvar7&#8243;,&nbsp;&raquo;petitvar8&#8243;,</p>
<p>167                               &laquo;&nbsp;petitvar9&#8243;,&nbsp;&raquo;petitvar10&#8243;,&nbsp;&raquo;petitvar11&#8243;,&nbsp;&raquo;petitvar12&#8243;,</p>
<p>168                               &laquo;&nbsp;petitvar13&#8243;,&nbsp;&raquo;petitvar14&#8243;,&nbsp;&raquo;petitvar15&#8243;,&nbsp;&raquo;petitvar16&#8243;,</p>
<p>169                               &laquo;&nbsp;petitvar17&#8243;,&nbsp;&raquo;petitvar18&#8243;,&nbsp;&raquo;petitvar19&#8243;,&nbsp;&raquo;petitvar20&#8243; );</p>
<p>170     rc = h_petit.DefineDone ();<br />
171<br />
172     /* Chargement de la table mémoire avec la table petit  */<br />
173<br />
174     do until ( fin_petit );<br />
175        set petit end = fin_petit;<br />
176        rc = h_petit.add ();<br />
177     end;<br />
178<br />
179     /* Création de la table fusionnée */<br />
180     do until ( fin_grand );<br />
181        set grand end = fin_grand;<br />
182        /*Initialisation des variables manquantes */<br />
183        do i=lbound(petitvar) to hbound(petitvar);<br />
184           petitvar(i) = .;<br />
185        end;<br />
186        rc = h_petit.find ();<br />
187        output;<br />
188     end;<br />
189  run;</p>
<p>Note:  63406 observations copiées de la table WORK.PETIT.<br />
Note:  315975 observations copiées de la table WORK.GRAND.<br />
Note: La table WORK.HASH_MERGE a 315975 observations et 703 variables.<br />
Note: La compression de la table WORK.HASH_MERGE a réduit la taille de 76.18 pourcent.<br />
Compression de 15055 pages; la décompression nécessiterait 63198 pages.<br />
Note: L&#8217;étape DATA used (Total process time):<br />
temps réel                   19.79 secondes<br />
temps processeur utilisateur 18.28 secondes<br />
temps processeur système     1.31 secondes<br />
Mémoire                            458k</p>
]]></content:encoded>
			<wfw:commentRss>http://cv-sas-mvs-unix-windows.001ordi.com/optimisation-sas/00081/sas-data-merge_contre-hashing.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

