Thema Datum  Von Nutzer Rating
Antwort
19.07.2020 13:58:10 Gast2202
NotSolved
19.07.2020 15:14:22 Gast14770
NotSolved
19.07.2020 16:28:10 Gast2202
NotSolved
19.07.2020 17:43:52 Gast24304
NotSolved
19.07.2020 23:12:21 Gast22403
NotSolved
19.07.2020 17:52:31 Gast60965
NotSolved
19.07.2020 18:48:50 Gast45553
NotSolved
19.07.2020 20:43:29 Gast2202
NotSolved
19.07.2020 20:44:19 Gast2202
NotSolved
20.07.2020 05:48:07 Gast67513
NotSolved
20.07.2020 19:18:42 xlKing
NotSolved
20.07.2020 19:27:34 Gast2202
NotSolved
20.07.2020 20:31:29 xlKing
NotSolved
20.07.2020 21:48:24 Gast2202
NotSolved
20.07.2020 23:16:26 Gast2202
NotSolved
20.07.2020 23:44:15 Mase
NotSolved
20.07.2020 23:48:50 Gast2202
NotSolved
21.07.2020 00:01:18 Mase
NotSolved
21.07.2020 00:06:02 Gast2202
NotSolved
22.07.2020 02:24:11 Gast44480
NotSolved
22.07.2020 02:30:38 Gast44480
NotSolved
22.07.2020 04:18:45 Gast2202
NotSolved
22.07.2020 09:56:24 Gast7105
NotSolved
22.07.2020 12:40:03 Gast46832
NotSolved
Rot Primzahlengenerator Ulrichs Vorschlag
21.07.2020 20:58:04 Ulrich
NotSolved
22.07.2020 14:00:46 Gast2202
NotSolved
22.07.2020 14:19:51 Ulrich
NotSolved
22.07.2020 15:50:28 Gast21224
NotSolved
22.07.2020 17:40:59 Gast95715
NotSolved
23.07.2020 11:45:25 Ulrich
NotSolved
23.07.2020 12:49:02 Mase
NotSolved

Ansicht des Beitrags:
Von:
Ulrich
Datum:
21.07.2020 20:58:04
Views:
659
Rating: Antwort:
  Ja
Thema:
Primzahlengenerator Ulrichs Vorschlag

Hallo,

auf den ersten Blick kommen mir drei Vorschläge zur Optimierung der Performance deiner Codes:

 

1.) Du schreibst jede Primzahl einzeln in die Zellen. Das kostet sehr viel Zeit. Zellzugriffe (lesen und schreiben) sind allgemein zeitintensiv. Eine Möglichkeit, das zu verbessern ist die Verwendung eines Arrays. Damit kannst du in der Schleife die Primzahlen in das Array schreiben und dann am Ende das gesamte Array in das Tabellenblatt übergeben.

 

2.) Die Codes prüfen ob ein Primzahlkandidat durch jede Zahl (bzw. jede ungerade) Zahl teilbar ist. Man könnte auch die bereits gewonnenen Ereknntnisse (Primzahlen!) verwenden, und ausschließlich testen, ob ein Kandidat durch bereits ermittelte Primzahlen teilbar ist. Dadurch wird bei wird die Anzahl der Schleifendurchläufe der Inneren Schleife erheblich reduziert.

 

3.) Variablen richtig deklarieren. Das bringt auf meinem Rechner auch noch etwas Geschwindigkeit (wusste ich auch nicht).

 

Hier mein Vorschlag und mein Testsetting (ich empfehel eine neue Datei zu verwenden):

Sub code1()
    Dim x1, x2, ti, i, max, pri
    i = 1
    ti = Timer
    max = 1000000
    For x1 = 2 To max
        pri = True
        For x2 = 2 To Sqr(x1)
            If x1 Mod x2 = 0 Then
                pri = False
                Exit For
            End If
        Next x2
        If pri Then
            Cells(i, 1) = x1
            i = i + 1
        End If
    Next x1
    'MsgBox Timer - ti
End Sub


Sub code2()
    Dim x1, x2, ti, i, max, pri
    i = 2
    ti = Timer
    max = 1000000
    Cells(1, 2) = 2
    For x1 = 3 To max Step 2
        pri = True
        For x2 = 3 To Sqr(x1) + 1 Step 2
            If x1 Mod x2 = 0 Then
                pri = False
                Exit For
            End If
        Next x2
        If pri Then
            Cells(i, 2) = x1
            i = i + 1
        End If
    Next x1
    'MsgBox Timer - ti
End Sub


Sub code1_arr()
    'Variante von code1: es wird ein Array verwendet um den Zellzugriff zu reduzieren
    Dim x1, x2, ti, i, max, pri
    Dim ar(1 To 80000, 1 To 1)
    i = 1
    ti = Timer
    max = 1000000
    For x1 = 2 To max
        pri = True
        For x2 = 2 To Sqr(x1)
            If x1 Mod x2 = 0 Then
                pri = False
                Exit For
            End If
        Next x2
        If pri Then
            ar(i, 1) = x1
            i = i + 1
        End If
    Next x1
    Cells(1, 3).Resize(UBound(ar), 1).Value = ar
End Sub


Sub code2_arr()
    'Variante von code2: es wird ein Array verwendet um den Zellzugriff zu reduzieren
    Dim x1, x2, ti, i, max, pri
    Dim ar(1 To 80000, 1 To 1)
    i = 2
    ti = Timer
    max = 1000000
    ar(1, 1) = 2
    For x1 = 3 To max Step 2
        pri = True
        For x2 = 3 To Sqr(x1) + 1 Step 2
            If x1 Mod x2 = 0 Then
                pri = False
                Exit For
            End If
        Next x2
        If pri Then
            ar(i, 1) = x1
            i = i + 1
        End If
    Next x1
    Cells(1, 4).Resize(UBound(ar), 1).Value = ar
End Sub


Sub vorschlag()
    Dim candidate As Long
    Dim max As Long
    Dim isPrime As Boolean
    Dim i As Long, i2 As Long
    Dim sqr_candidate As Double
    Dim primes(1 To 80000, 1 To 1) As Long
    max = 1000000
    
    i = 1
    primes(i, 1) = 2
    primes(2, 1) = 3
    For candidate = 3 To max Step 2
        isPrime = True
        i2 = 2
        sqr_candidate = Sqr(candidate)
        Do Until primes(i2, 1) > sqr_candidate
            If candidate Mod primes(i2, 1) = 0 Then
                isPrime = False
                Exit Do
            End If
            i2 = i2 + 1
        Loop
        If isPrime Then
            i = i + 1
            primes(i, 1) = candidate
        End If
    Next candidate
    
    Cells(1, 5).Resize(i, 1).Value = primes
End Sub


Sub test_them()
Dim i As Long, t

Const n = 2 'Anzahl der Makroaufrufe

    'damit der gesamte code kompiliert ist
    'und etwaigen overhead zu Beginn "nicht so erheblich mitmessen"
    Call code1
    Call code2
    Call code1_arr
    Call code2_arr
    Call vorschlag

    'eigentlicher Vergleich
    t = Timer
    For i = 1 To n
        Call code1
    Next
    Debug.Print "code1: ", Timer - t

    t = Timer
    For i = 1 To n
        Call code1_arr
    Next
    Debug.Print "code1_arr: ", Timer - t

    t = Timer
    For i = 1 To n
        Call code2
    Next
    Debug.Print "code2: ", Timer - t

    t = Timer
    For i = 1 To n
        Call code2_arr
    Next
    Debug.Print "code2_arr: ", Timer - t

    t = Timer
    For i = 1 To n
        Call vorschlag
    Next
    Debug.Print "vorschlag: ", Timer - t

    msgbox "fertig: siehe Direktfenster"
End Sub

code1 und code2 habe ich von dir übernommen. code1_arr und code2_arr nutzen ein Array und greifen so nur einmalig auf das Tabellenblatt zu.
"vorschlag" ist mein Vorschlag, in dem ich alle oben aufgeführten Ideen zu deinen Codes umgesetzt habe.

 

Das Makro "test_them" schreibt die gemessenen Zeiten in das Direktfenster der VBE.

Viele Grüße,
Ulrich


Ihre Antwort
  • Bitte beschreiben Sie Ihr Problem möglichst ausführlich. (Wichtige Info z.B.: Office Version, Betriebssystem, Wo genau kommen Sie nicht weiter)
  • Bitte helfen Sie ebenfalls wenn Ihnen geholfen werden konnte und markieren Sie Ihre Anfrage als erledigt (Klick auf Häckchen)
  • Bei Crossposting, entsprechende Links auf andere Forenbeiträge beifügen / nachtragen
  • Codeschnipsel am besten über den Code-Button im Text-Editor einfügen
  • Die Angabe der Emailadresse ist freiwillig und wird nur verwendet, um Sie bei Antworten auf Ihren Beitrag zu benachrichtigen
Thema: Name: Email:



  • Bitte beschreiben Sie Ihr Problem möglichst ausführlich. (Wichtige Info z.B.: Office Version, Betriebssystem, Wo genau kommen Sie nicht weiter)
  • Bitte helfen Sie ebenfalls wenn Ihnen geholfen werden konnte und markieren Sie Ihre Anfrage als erledigt (Klick auf Häckchen)
  • Bei Crossposting, entsprechende Links auf andere Forenbeiträge beifügen / nachtragen
  • Codeschnipsel am besten über den Code-Button im Text-Editor einfügen
  • Die Angabe der Emailadresse ist freiwillig und wird nur verwendet, um Sie bei Antworten auf Ihren Beitrag zu benachrichtigen

Thema Datum  Von Nutzer Rating
Antwort
19.07.2020 13:58:10 Gast2202
NotSolved
19.07.2020 15:14:22 Gast14770
NotSolved
19.07.2020 16:28:10 Gast2202
NotSolved
19.07.2020 17:43:52 Gast24304
NotSolved
19.07.2020 23:12:21 Gast22403
NotSolved
19.07.2020 17:52:31 Gast60965
NotSolved
19.07.2020 18:48:50 Gast45553
NotSolved
19.07.2020 20:43:29 Gast2202
NotSolved
19.07.2020 20:44:19 Gast2202
NotSolved
20.07.2020 05:48:07 Gast67513
NotSolved
20.07.2020 19:18:42 xlKing
NotSolved
20.07.2020 19:27:34 Gast2202
NotSolved
20.07.2020 20:31:29 xlKing
NotSolved
20.07.2020 21:48:24 Gast2202
NotSolved
20.07.2020 23:16:26 Gast2202
NotSolved
20.07.2020 23:44:15 Mase
NotSolved
20.07.2020 23:48:50 Gast2202
NotSolved
21.07.2020 00:01:18 Mase
NotSolved
21.07.2020 00:06:02 Gast2202
NotSolved
22.07.2020 02:24:11 Gast44480
NotSolved
22.07.2020 02:30:38 Gast44480
NotSolved
22.07.2020 04:18:45 Gast2202
NotSolved
22.07.2020 09:56:24 Gast7105
NotSolved
22.07.2020 12:40:03 Gast46832
NotSolved
Rot Primzahlengenerator Ulrichs Vorschlag
21.07.2020 20:58:04 Ulrich
NotSolved
22.07.2020 14:00:46 Gast2202
NotSolved
22.07.2020 14:19:51 Ulrich
NotSolved
22.07.2020 15:50:28 Gast21224
NotSolved
22.07.2020 17:40:59 Gast95715
NotSolved
23.07.2020 11:45:25 Ulrich
NotSolved
23.07.2020 12:49:02 Mase
NotSolved