Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
968to972
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
968to972
968to972
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Code wird immer langsamer

Code wird immer langsamer
12.04.2008 13:55:04
Jenny
Hallo Ihr Lieben,
Ich habe unten stehenden Code, der auch genau das macht, was er soll.
Aber leider wird er von Runde zu Runde langsamer, daran ändert auch das Gefummel an ScreenUpdating und Calculation nichts.
Weiß jemand von Euch, woran das liegt, bzw. wie man das verhindern kann?
Danke bereits im Voraus!

Sub test()
Dim a%, b%, c%, s&, x&, Z, t!
t = Timer
Set Z = CreateObject("scripting.dictionary")
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 100
For b = 1 To 100
For c = 1 To 100
x = x + 1
Z(x) = a & ";" & b & ";" & c
If x = 1000 Then
Debug.Print Timer - t
t = Timer
s = s + 1
x = 0
Cells(4, s).Resize(Z.Count) = WorksheetFunction.Transpose(Z.items)
End If
Next c
Next b
Next a
End Sub


Grüße von Jenny im Excel-Land

17
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Code wird immer langsamer
12.04.2008 14:04:00
Reinhard
Hi Jenny,
m.E. wächst pro Runde Z() immer um eine Zeile durch Resize, und je größer es ist desto länger dauert Transpose:

Sub test()
Dim a%, b%, c%, s&, x&, Z, t!
t = Timer
Set Z = CreateObject("scripting.dictionary")
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 100
For b = 1 To 100
For c = 1 To 100
x = x + 1
Z(x) = a & ";" & b & ";" & c
If x = 1000 Then
Debug.Print Timer - t
t = Timer
s = s + 1
x = 0
'Cells(4, s).Resize(Z.Count) = WorksheetFunction.Transpose(Z.items)
Cells(4, s) = WorksheetFunction.Transpose(Z.items)
End If
Next c
Next b
Next a
End Sub

Gruß
Reinhard

Anzeige
AW: Code wird immer langsamer
12.04.2008 14:30:22
Jenny
Hallo Reinhard,
deine Änderung im Code hatte ich einfach übersehen, sorry!!!
Aber leider erfolgt bei deinem Code nur eine Ausgabe in Zeile 4, aber nicht darunter.
Grüße von Jenny im Excel-Land

AW: Code wird immer langsamer
12.04.2008 14:06:10
Nepumuk
Hallo Jenny,
das kommt dadurch, dass das Dictionary-Objekt immer voller wird.
Gruß
Nepumuk

AW: Code wird immer langsamer
12.04.2008 14:16:00
Jenny
Hallo Ihr beiden,
danke für die schnellen Antworten!
@Reinhard: Daran kann es eigentlich nicht liegen, denn Z.Count bleibt konstant bei 1000 in jeder If-Schleife und auch die Ausgabe in der Tabelle reicht jedesmal bis zur gleichen Zeile.
@Nepumuk: Wieso wird das Dictionary-Objekt immer größer? Ich überschreibe doch lediglich die alten Werte, deshalb bleibt Z.Count doch auch maximal 1000.
Habt Ihr noch einen Tipp?
Grüße von Jenny im Excel-Land

Anzeige
AW: Code wird immer langsamer
12.04.2008 14:23:34
Reinhard
Hallo Jenny,
hast du meinen Code mal laufen gelassen!?
Da wird immer die gleiche Zeit angezeigt.
Naja, seltenst auch Zeit=0 was mich schon sehr wundert daß Excel gar so schnell ist :-)
Gruß
Reinhard

AW: Code wird immer langsamer
12.04.2008 14:18:00
Daniel
Hi
naja, die Calculation ausschalten hilft dir auch nicht viel weiter, weil es wird ja nichts berechnet.
dir ist aber schon klar, daß du mit diesem Code 1 Mio Datensätzen mit 1000 Zeilen in 1000 Spalten erzeugst?
also nur für Office2007-Anwender einsetzbar.
folgende Zeitfresse könntest du noch rausnehmen:
- Das Debug-Print ist ja eingentlich übeflüssig (ist wahrscheinlich eh nur zu Testzwecken drin)
des weiteren könntest du noch zur Beschleunigung alle daten in eine Arry-Variable (1000x1000) speichern und diese erst am schluss nach Excel zurückschreiben.

Sub test()
Dim a%, b%, c%, s&, x&, Z, t!
Dim Erg(1 To 1000, 1 To 1000)
t = Timer
s = 1
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 100
For b = 1 To 100
For c = 1 To 100
x = x + 1
Erg(x, s) = a & ";" & b & ";" & c
If x = 1000 Then
s = s + 1
x = 0
End If
Next c
Next b
Next a
Cells(4, 1).Resize(UBound(Erg, 1), UBound(Erg, 2)).Value = Erg
End Sub


Gruß, Daniel

Anzeige
AW: Code wird immer langsamer
12.04.2008 14:33:00
Jenny
Hallo Daniel,
deine Idee ist prima!
Leider arbeitet mein kleiner Rechner bei Excel2007 schon an der Belastungsgrenze, wegen mangelnden Arbeitsspeichers.
Dadurch schmiert er mir bei größeren Arrays häufiger mal ab und deshalb die Variante, mehrere kleinere Arrays aufzuziehen.
Grüße von Jenny im Excel-Land

AW: Code wird immer langsamer
12.04.2008 14:43:47
Daniel
Hi
dann verwende doch ein einspaltiges Array anstelle des Dictionary-Objekts.
das dürfte eigentlich nicht grösser werden, da die Grösse fest definiert ist und die Werte immer wieder überschrieben werden.
Es gibt eigentlich keinen Grund, das Dictionary-Objekt zu verwenden, da es bei deiner Anwendung gebenüber dem einfachen Array keinen Vorteil bringt.
durch die schleifen ist sichergestellt, daß es keine Doppelten Werte gibt und die Sortierung passt auch.
Gruß, Daniel

Anzeige
AW: Code wird immer langsamer
12.04.2008 14:56:32
Jenny
Hallo Daniel,
einerseits wollte ich meine Programmierkenntnisse mit dem Dictionary-Objekt verbessern, andererseits höre ich immer wieder, daß das Dictionary-Objekt wesentlich schneller ist als ein Array. Daher die Idee.
Die ersten 10 Spalten werden vom Dictionary auch bestimmt 10x schneller erstellt als beim Array.
Ich muss jetzt erstmal los, werde aber heute abend wieder vorbeischauen.
Grüße von Jenny im Excel-Land

AW: Code wird immer langsamer
12.04.2008 15:21:00
Daniel
Hi
also bei mir ist die Arry-Variante auf jeden Fall geringfügig schneller als das Scriping-objekt (bei 100 Spalten c.a. eine Halbe Sekunde , 8,7 zu 9,2)
allerdings ist es schon besser, die Spalten einzeln zurück zu schreiben, als erst alles in einem Array zu sammeln.
diese Variange braucht bei mir am länsten (14 sec)
zum Testen habe ich den Schleifendurchlauf für a immer auf 10 berschränkt, da sonst mein Excel2002 nicht mitmacht.
hier mal beide Varianten zum Testen
Option Explicit

Sub test()
Dim a%, b%, c%, s&, x&, Z, t!
t = Timer
Set Z = CreateObject("scripting.dictionary")
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 10
For b = 1 To 100
For c = 1 To 100
x = x + 1
Z(x) = a & ";" & b & ";" & c
If x = 1000 Then
s = s + 1
x = 0
Cells(4, s).Resize(Z.Count) = WorksheetFunction.Transpose(Z.items)
End If
Next c
Next b
Next a
Debug.Print Timer - t
End Sub



Sub test1()
Dim a%, b%, c%, s&, x&, Z, t!
Dim erg(1 To 1000, 1 To 1)
t = Timer
Set Z = CreateObject("scripting.dictionary")
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 10
For b = 1 To 100
For c = 1 To 100
x = x + 1
erg(x, 1) = a & ";" & b & ";" & c
If x = 1000 Then
s = s + 1
x = 0
Cells(4, s).Resize(1000, 1).Value = erg
End If
Next c
Next b
Next a
Debug.Print Timer - t
End Sub


Anzeige
Bitte mal testen
12.04.2008 20:58:00
Jenny
Hallo Daniel,
da bin ich wieder.
Du hast recht; in diesem Fall scheinen Array und Dictionary wirklich etwa gleich schnell zu arbeiten.
Aber das klärt leider immernoch nicht meine Ausgangsfrage, denn beide Codes weisen das gleiche Phänomen auf:
Sie werden mit der Zeit langsamer!
Lass doch bitte beide Codes bei dir mal laufen, kopiere den Direktbereich in ein Tabellenblatt und erstelle aus den Werten ein (Linien-)Diagramm!
Bei mir ist in beiden Fällen ein klarer linearer Anstieg zu erkennen.
Ist das bei dir auch so?
(Alle anderen, die Lust haben, sind natürlich auch gerne aufgefordert.)
Danke schonmal!
Grüße von Jenny im Excel-Land

Sub testDictionary()
Dim a%, b%, c%, s&, x&, Z, t!
t = Timer
Set Z = CreateObject("scripting.dictionary")
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 100
For b = 1 To 100
For c = 1 To 100
x = x + 1
Z(x) = a & ";" & b & ";" & c
If x = 10000 Then
Debug.Print Timer - t
t = Timer
s = s + 1
x = 0
Cells(4, s).Resize(Z.Count) = WorksheetFunction.Transpose(Z.items)
'Z.RemoveAll (hat keinerlei Effekt, sondern verlangsamt nur)
End If
Next c
Next b
Next a
End Sub



Sub testArray()
Dim a%, b%, c%, s&, x&, t!
Dim erg(1 To 10000, 1 To 1)
t = Timer
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 100
For b = 1 To 100
For c = 1 To 100
x = x + 1
erg(x, 1) = a & ";" & b & ";" & c
If x = 10000 Then
Debug.Print Timer - t
t = Timer
s = s + 1
x = 0
Cells(4, s).Resize(10000, 1).Value = erg
End If
Next c
Next b
Next a
End Sub


Anzeige
AW: Bitte mal testen
15.04.2008 21:51:07
Reinhard
Hi Jenny,
ich konnte nur den unteren Code testen und da brauch ich kein Diagramm, das wächst sehr deutlich, also die Zeit.
Der obere Code, da kommt laufzeitfehler 13, Typen unverträglich in Zeile
Cells(4, s).Resize(Z.Count) = WorksheetFunction.Transpose(Z.items)
an/in den Msgboxen siehste ja was ich schon probierte, irgendwas muß ich übersehen, denn bei deinem Anfangsposting gings ja auch
ich hab XL2000
Gruß
Reinhard

Option Explicit
Sub testDictionary()
Dim a%, b%, c%, s&, x&, Z, t!
t = Timer
Set Z = CreateObject("scripting.dictionary")
Cells(4, 1).CurrentRegion.Clear
For a = 1 To 100
For b = 1 To 100
For c = 1 To 100
x = x + 1
Z(x) = a & ";" & b & ";" & c
If x = 10000 Then
Debug.Print Timer - t
t = Timer
s = s + 1
x = 0
'MsgBox s     ' 1
'MsgBox Cells(4, s).Resize(Z.Count).Address   ' a4:A10003
'MsgBox Z.Count  '10000
'MsgBox TypeName(Z.items)   ' variant()
'MsgBox Z.items.Count    'Fehler Object erforderlich
'MsgBox TypeName(WorksheetFunction.Transpose(Z.items))
Cells(4, s).Resize(Z.Count) = WorksheetFunction.Transpose(Z.items)
'Z.RemoveAll (hat keinerlei Effekt, sondern verlangsamt nur)
End If
Next c
Next b
Next a
End Sub


Anzeige
AW: Bitte mal testen
15.04.2008 22:08:00
Jenny
Hallo Reinhard,
danke für deine Antwort!
Am Wochenende habe ich es auch mit Excel2000 (oder Excel 2002?, 2003?) getestet und bekam auch eine Fehlermeldung: "Typen unverträglich" oder so.
Als ich dann allerdings die Schleifenlänge verkleinerte (1 To 20) lief's auch dort, aber auch mit steigender Zeit.
Die Fehlermeldung bei
MsgBox Z.items.Count
erhalte ich auch bei Excel2007.
Aber WARUM, zum Teufel?
Die items werden doch korrekt aufgelistet, oder etwa nicht?
Grüße von Jenny im Excel-Land

AW: Bitte mal testen
15.04.2008 22:34:36
Reinhard
Hallo Jenny,
mir ist da einiges unklar, übrigens kenne ich scripting.dictionary erst seit ich deinen Beitrag sah :-)
Ich bin also genau der Fachmann dafür *lächel*
Aber, vielleicht hast du es nicht bekommen, aufgrund deiner Anfrage habe ich selbst hier nachgefragt was denn das fürn Kram ist dieses scripting dictonary, daraufhin nannte mir Renee gleich 3 Links wo es erklärt wird, schau mal hier im Forum, wirste leicht finden weil das Wort im Betreff vorkommt.
Und durchblicken tue ich schon längst nicht mehr, durch ausprobieren kam ich darauf daß es mit 1000 in deinem Code klappt, mit 10000 nicht (bei XL2000)
und das mit z.items.count verstehe ich genausowenig u.v.m.
Aber ich habe die Links noch nicht aufmerksam durchgelesen, ist mir zuviel Englisch.
Naja, wenn ich oder du auf den angegeben Links nix entdecken stellt halt einer eine neue Anfrage zu der Funktion, bezogen auf die seltsamen Fehler.
Gruß
Reinhard

Anzeige
AW: Bitte mal testen
15.04.2008 22:39:00
Reinhard
Hi Jenny,
der Beitrag hatte im Betreff Createobject, aber ich habe ihn gefunden, hier sind die 3 Links von Renee:
***************************
Hi Reinhard,
Als Einstieg: http://msdn2.microsoft.com/de-de/library/7t9k08y5(VS.80).aspx
Zu Scriptings: http://msdn2.microsoft.com/en-us/library/ms950396.aspx
Zu scripting.dictionary: http://msdn2.microsoft.com/en-us/library/x4k5wbx4(VS.85).aspx
usw. usf.
GreetZ Renée
************************************************
Gruß
Reinhard

Anzeige
AW: Bitte mal testen
15.04.2008 22:46:48
Jenny
Hallo Reinhard,
den hatte ich aufgrund deines Hinweises auch gerade entdeckt.
10 sek später hätte ich auch darauf verlinkt.
Morgen werfe ich mal einen Blick drauf, aber heute kann ich das wohl nicht mehr begreifen.
Vielen Dank für deine Mühe und viel Erfolg weiterhin!
Grüße von Jenny im Excel-Land

Fehler 13 typen unverträglich bei transpose
16.04.2008 01:14:00
Reinhard
Hallo Jenny,
ich kam zwar durch einfaches Ausprobieren auch auf 5461 als Maximalanzahl, aber konnte mir dies krumme Zahl genau wie die 21,xx de ich auch hatte, obwohl was völlig andere Berechnungen durchführte, nicht erklären.
Leider kam ich nicht auf die Idee mal nach diesen 5461 zu googeln, may be ich wäre schneller gewesen.
So dauerte es dann doch lange bis ich zur Lösung kam warum es zum Fehler kommt.
Gefunden auf www.xlam.ch steht die Aufklärung im Anhang.
Da es vielleicht den einen oder anderen interessieren könnte wegen Transpose, stelle ich die Frage auf noch offen. Betreff habe ich wegen dem Archiv angepasst.
Also bitte diesen diesen Beitrag erst in 1-2 Tagen "zumachen" oder als noch "offen" ins Archiv wandern lassen. Danke.
@Jenny, du hast ja einen neuen Thread laufen, also störts dich sicher nicht, wenn ich hier dies "anhänge", abgesehen davon daß du ja auch wissen wolltest warum da Fehler 13 kam.
Achja, der Fehler kommt bei XL2000, bei höheren Versionen weiß ich nicht was da wann geschieht.
Gruß
Reinhard
Beitrag stammt aus der Rätselecke von xlam.ch:
Wieso ist die maximale Anzahl Elemente eines Arrays in der Microsoft Excel-Referenz mit 5'461 Elementen angeben? Weshalb nicht eine häufig vorkommende Zahl wie zum Beispiel 4'096?
Antwort:
Meistens besitzen Limitationen eine häufig vorkommende Zahl wie zum Beispiel 256 (bzw. 255), 1'024, 32'768 (bzw. 32'767) oder 65'536, also alles Werte, die durch 256 ohne Rest teilbar sind. Zum Speichern von Zahlen von 0 bis 255 (256 verschiedene Zahlen) wird 1 Byte (8 Bit) benötigt. Zum Speichern von Zahlen von 0 bis 65'535 (65'536 verschiedene Zahlen) werden 2 Bytes benötigt (256 * 256 = 65'536). Teilt man jedoch die Zahl 5'461 durch 256, so erhält man 21.33203125, d.h. einen Wert, der überhaupt nicht zu den sonst üblichen Zahlen passt. Die Limitation von maximal 5'461 Array-Elementen besitzt einen anderen Grund:
Array-Definitionen werden in Microsoft Excel in zwei je 64 KB grossen Speichersegmenten abgelegt. Ein 64 KB Speichersegment ist in Bytes ausgedrückt 65'536 Bytes gross (1 KB = 1'024 Bytes). Da Arrayelement-Werte als 24 Bit-Wert gespeichert werden, können zwei 64 KB Speichersegmente maximal 5'461 Elemente enthalten (2 * 65'536 / 24 = 5'461.33 = 5'461).

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige