Dieses Forum nutzt Cookies
Dieses Forum verwendet Cookies, um deine Login-Informationen zu speichern, wenn du registriert bist, und deinen letzten Besuch, wenn du es nicht bist. Cookies sind kleine Textdokumente, die auf deinem Computer gespeichert werden. Die von diesem Forum gesetzten Cookies werden nur auf dieser Website verwendet und stellen kein Sicherheitsrisiko dar. Cookies aus diesem Forum speichern auch die spezifischen Themen, die du gelesen hast und wann du zum letzten Mal gelesen hast. Bitte bestätige, ob du diese Cookies akzeptierst oder ablehnst.

Ein Cookie wird in deinem Browser unabhängig von der Wahl gespeichert, um zu verhindern, dass dir diese Frage erneut gestellt wird. Du kannst deine Cookie-Einstellungen jederzeit über den Link in der Fußzeile ändern.

[Excel] Performance-Test verschiedener VERGLEICHe
#1
Ich habe eben eine kleine Performance-Messroutine geschrieben.

In dieser sind A:B durchgehende Zufallsdaten der Form A: [A-Z][A-Z][A-D] und B: [A-Z][A-Z] (also über 1048576 bzw. 65536 Zeilen).

Für D:E (entsprechend A:B) kann man in der Routine mit n eingeben, wie viele VERGLEICH-Formeln gerechnet werden sollen. n=30 bedeutet also 30 gleiche Formeln, die sich jeweils über knapp 2,1 Mio (=2^21) Daten her machen.

Verglichen werden {SUMME}, VERGLEICH, {VERGLEICH}, AGGREGAT, SUMMENPRODUKT und SUMMEWENNS.

1. Manchmal wird unterschieden, ob (A:A=D1)*(B:B=E1) oder (A:A&B:B=D1&E1) als Kriterium gerechnet wird. Überraschende Ergebnisse!

2. Bei VERGLEICH wird innen mit INDEX(A:A&B&B;) gerechnet. Auch hier eine Überraschung, die sich etwa hälftig auf den Effekt zu 1. sowie die Verwendung von INDEX statt {} aufteilt.

Ergebnisse:
1. AGGREGAT ist VERGLEICH soweit ebenbürtig (neopa hat recht)
2. {} scheint gegenüber ...INDEX(;)... im Vorteil zu sein (WF hat recht)

Es kommt aber erheblich auf den Einzelfall an. Auch kommt es ein wenig drauf an, ob das Arbeitsblatt frisch ist, oder das Makro schon mehrmals gelaufen ist (wie hier. Dann langsamer).

Anmerkung: Gibt es mehr als ein Auftreten, zeigen VERGLEICH und AGGREGAT das erste, VERWEIS das letzte und die Summenfunktionen deren Addition. Das muss dem Anwender klar sein.

Hier die Einzelergebnisse in Sekunden für n=30 und n=100 (Win10, xl2010, Surface Pro 4, Intel m3, 4 Kerne):

F: 023,87:  =VERGLEICH(D1&E1;INDEX(A:A&B:B;);)
G: 006,82: {=VERGLEICH(D1&E1;A:A&B:B;)}
H: 020,00:  =VERWEIS(2;1/(A:A&B:B=D1&E1);ZEILE(A:A))
I: 010,68:  =SUMMENPRODUKT(ZEILE(A:A)*(A:A=D1)*(B:B=E1))
J: 011,14:  =SUMMENPRODUKT(ZEILE(A:A);N(A:A=D1);N(B:B=E1))
K: 008,92: {=SUMME(ZEILE(A:A)*(A:A=D1)*(B:B=E1))}
L: 022,03:  =AGGREGAT(15;6;ZEILE(A:A)/(A:A&B:B=D1&E1);1)
M: 011,16:  =AGGREGAT(15;6;ZEILE(A:A)/(A:A=D1)/(B:B=E1);1)
N: 003,55:  =SUMMEWENNS(C:C;A:A;D1;B:B;E1)
O: 012,55:  =SUMMENPRODUKT(C:C;N(A:A=D1);N(B:B=E1))
P: 025,09:  =SUMMENPRODUKT(C:C;N(A:A&B:B=D1&E1))
Q: 010,84:  =SUMMENPRODUKT(C:C;-(A:A=D1);-(B:B=E1))
R: 011,01:  =SUMMENPRODUKT(C:C;--(A:A=D1);--(B:B=E1))
S: 011,75:  =SUMMENPRODUKT(C:C;1*(A:A=D1);1*(B:B=E1))
T: 012,00:  =SUMMENPRODUKT(C:C;0+(A:A=D1);0+(B:B=E1))
U: 010,99:  =VERWEIS(2;1/(A:A=D1)/(B:B=E1);ZEILE(A:A))

F: 069,23:  =VERGLEICH(D1&E1;INDEX(A:A&B:B;);)
G: 017,79: {=VERGLEICH(D1&E1;A:A&B:B;)}
H: 065,76:  =VERWEIS(2;1/(A:A&B:B=D1&E1);ZEILE(A:A))
I: 033,02:  =SUMMENPRODUKT(ZEILE(A:A)*(A:A=D1)*(B:B=E1))
J: 035,79:  =SUMMENPRODUKT(ZEILE(A:A);N(A:A=D1);N(B:B=E1))
K: 027,73: {=SUMME(ZEILE(A:A)*(A:A=D1)*(B:B=E1))}
L: 073,49:  =AGGREGAT(15;6;ZEILE(A:A)/(A:A&B:B=D1&E1);1)
M: 035,02:  =AGGREGAT(15;6;ZEILE(A:A)/(A:A=D1)/(B:B=E1);1)
N: 011,36:  =SUMMEWENNS(C:C;A:A;D1;B:B;E1)
O: 038,11:  =SUMMENPRODUKT(C:C;N(A:A=D1);N(B:B=E1))
P: 077,49:  =SUMMENPRODUKT(C:C;N(A:A&B:B=D1&E1))
Q: 034,25:  =SUMMENPRODUKT(C:C;-(A:A=D1);-(B:B=E1))
R: 034,03:  =SUMMENPRODUKT(C:C;--(A:A=D1);--(B:B=E1))
S: 036,75:  =SUMMENPRODUKT(C:C;1*(A:A=D1);1*(B:B=E1))
T: 036,54:  =SUMMENPRODUKT(C:C;0+(A:A=D1);0+(B:B=E1))
U: 034,75:  =VERWEIS(2;1/(A:A=D1)/(B:B=E1);ZEILE(A:A))

Hier noch der Code (mit n = 5, damit es beim Erstdurchlauf nicht zu lange dauert):


Code:
Sub TimerOfLookups()
   [1:1].RowHeight = 13: n = 5: Cells.Clear: Range("F1:U" & n) = "not done yet": [C1] = "1": [C:C].DataSeries
   Range("A:A,D1:D" & n).FormulaR1C1 = "=CHAR(RAND()*26+65)&CHAR(RAND()*26+65)&CHAR(RAND()*4+65)"
   [A:A] = [A:A].Value: Range("D1:D" & n) = Range("D1:D" & n).Value
   Range("B:B,E1:E" & n).FormulaR1C1 = "=CHAR(RAND()*26+65)&CHAR(RAND()*26+65)"
   [B:B] = [B:B].Value: Range("E1:E" & n) = Range("E1:E" & n).Value
   Call Kalk("F", n, False, "=MATCH(RC[-2]&RC[-1],INDEX(C[-5]&C[-4],),)")
   Call Kalk("G", n, True, "=MATCH(RC[-3]&RC[-2],C[-6]&C[-5],)")
   Call Kalk("H", n, False, "=LOOKUP(2,1/(C[-7]&C[-6]=RC[-4]&RC[-3]),ROW(C[-7]))")
   Call Kalk("I", n, False, "=SUMPRODUCT(ROW(C[-8])*(C[-8]=RC[-5])*(C[-7]=RC[-4]))")
   Call Kalk("J", n, False, "=SUMPRODUCT(ROW(C[-9]),N(C[-9]=RC[-6]),N(C[-8]=RC[-5]))")
   Call Kalk("K", n, True, "=SUM(ROW(C[-10])*(C[-10]=RC[-7])*(C[-9]=RC[-6]))")
   Call Kalk("L", n, False, "=AGGREGATE(15,6,ROW(C[-11])/(C[-11]&C[-10]=RC[-8]&RC[-7]),1)")
   Call Kalk("M", n, False, "=AGGREGATE(15,6,ROW(C[-12])/(C[-12]=RC[-9])/(C[-11]=RC[-8]),1)")
   Call Kalk("N", n, False, "=SUMIFS(C[-11],C[-13],RC[-10],C[-12],RC[-9])")
   Call Kalk("O", n, False, "=SUMPRODUCT(C[-12],N(C[-14]=RC[-11]),N(C[-13]=RC[-10]))")
   Call Kalk("P", n, False, "=SUMPRODUCT(C[-13],N(C[-15]&C[-14]=RC[-12]&RC[-11]))")
   Call Kalk("Q", n, False, "=SUMPRODUCT(C[-14],-(C[-16]=RC[-13]),-(C[-15]=RC[-12]))")
   Call Kalk("R", n, False, "=SUMPRODUCT(C[-15],--(C[-17]=RC[-14]),--(C[-16]=RC[-13]))")
   Call Kalk("S", n, False, "=SUMPRODUCT(C[-16],1*(C[-18]=RC[-15]),1*(C[-17]=RC[-14]))")
   Call Kalk("T", n, False, "=SUMPRODUCT(C[-17],0+(C[-19]=RC[-16]),0+(C[-18]=RC[-15]))")
   Call Kalk("U", n, False, "=LOOKUP(2,1/(C[-20]=RC[-17])/(C[-19]=RC[-16]),ROW(C[-20]))")
   MsgBox [DA1]
End Sub

Sub Kalk(Spalte, n, Arr As Boolean, Formel): a = Timer
  If Arr Then
     Range(Spalte & "1").FormulaArray = Formel: Range(Spalte & "1:" & Spalte & n).FillDown
  Else
     Range(Spalte & "1:" & Spalte & n).FormulaR1C1 = Formel
  End If: b = Timer - a
  Formel = Range(Spalte & "1").FormulaLocal
  Range(Spalte & "1:" & Spalte & n) = Range(Spalte & "1:" & Spalte & n).Value
  Range("A" & Spalte & "1") = b
  Range("B" & Spalte & "1").FormulaR1C1 = "=TEXT(RC[-26],""000,00"")"
  Range("C" & Spalte & "1") = IIf(Arr, "{", " ") & Formel & IIf(Arr, "}", " ")
  [DA1] = [DA1] & Chr(10) & Spalte & ": " & Range("B" & Spalte & "1") & ": " & Range("C" & Spalte & "1")
End Sub
Antworten Top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste