Hallo zusammen, @FreelanceReinh: Vielen Dank für Deine Hinweise. Ojhe, ist das peinlich ... da habe ich wohl den Wald vor lauter Bäumen nicht gesehen und war mehr auf den Algorhythmus konzentriert, als auf SAS. Eine Typkonvertierung hatte ich ja auch im Kommentar und wollte von String mit INT() auf numerisch konvertieren statt mit INPUT ... eieiei. Anbei (der Vollständigkeit halber) mein korrigierter Code. Ich habe nur die Notes im Log bereinigt, wobei ich wirklich erstaunt bin wie viel schneller eine alternative Verarbeitung ohne Strings laufen kann. Zusätzlich habe ich mir erlaubt die gesuchte Nummer maximal 15 Stellen lang werden zu lassen statt 20. Wenn man die Lösung kennt, kann man natürlich auf 11 einschränken und mehr Performance gewinnen.
DATA _null_;
length findme $15.;
start_number = 18990000000;
end_number = 99999999999;
DO n = start_number TO end_number;
findme = PUT(n,15.-l);
digits = length(findme);
quersumme = 0;
/*rc=dosubl(cats('SYSECHO "n=',n,'"'));*/
/* Quersumme berechnen */
DO i = 1 TO digits;
quersumme = quersumme + INPUT(substr(findme,i,1),1.);
END;
/* Test: durch 10 teilbar? */
IF MOD(quersumme,10) EQ 0 THEN DO;
findlag = lag(findme);
/* Quersumme der vorherigen Zahl auch durch 10 teilbar? */
IF SUM(INPUT(findlag,15.),1) EQ INPUT(findme,15.) THEN DO;
PUT "Ergebnis: " findlag " und " findme;
STOP;
END;
END;
END;
RUN;
Was mich ja wundert ist die Tatsache, dass die automatische Konvertierung von SAS tatsächlich performanter läuft, als wenn man das selbst angibt. Ich komme auf Laufzeiten, die sich um 10-25% unterscheiden. Den Hinweis mit "dosubl" für die Ausgabe im eGuide finde ich klasse, das sorgt in meinem Data-Step jedoch für mehr als doppelt so lange Laufzeiten. (FULL)STIMER liefert meist gute Werte. Mir fehlt jedoch eine Option, unterschiedliche Lösungen im Detail zu testen. Beispiel: Deklaration der zu durchlaufenden Zahlen einmal im DATA-Step vor der DO-Schleife und einmal die direkte Angabe in der DO-Schleife.
[...]
start_number = 18990000000;
end_number = 99999999999;
DO n = start_number TO end_number;
[...]
vs
[...]
DO n = 18990000000 TO 99999999999;
[...]
Oder per Macro-Variable, wie man es natürlich auch machen kann. Hier liegen die Zeitunterschiede vermutlich in einem sehr kleinen Bereich, wodurch das schlecht im Log nachvollziehbar ist. Da können wahrscheinlich parallel laufende Zugriffe im System mehr Einfluss auf das Log haben. Dennoch würde mich interessieren, ob es Unterschiede gibt oder nicht. Reine Neugier 🙂 @AndreasMenrath: Führt SAS das Length-Statement wirklich 10 mal aus, wenn es im Schleifen-Kopf steht? Damit hätte ich nicht gerechnet. Ich habe es jetzt im Code voran gestellt, konnte jedoch keine wesentlichen Unterschiede in der Laufzeit feststellen. (Auch wieder so ein Thema, das ich gerne genauer prüfen würde)
Beste Grüße in die Runde
Michael
... View more