Geschwindigkeiten beim Kopieren und Zippen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Fakiz.

    Geschwindigkeiten beim Kopieren und Zippen

    Moin zusammen

    Ich habe gleich 2 Fragen bzgl der "Geschwindigkeit" von Programmen und der Geschwindigkeit beim kopieren und zippen.

    1.) Gestern habe ich gelesen, das die Geschwindigkeits Unterschiede zwischen VB.net und C# Programmen gar nicht so gravierend sein sollen. :?:

    2.) Ich habe nun meinen Code bzgl des copy und zip noch etwas "verbessert".
    Nun wollte ich mal fragen ob das "gute" Werte sind.

    Gegeben ist ein PC mit folgendem:
    I3 3225 mit 3,3GHz 16GB RAM Win 7 64Bit
    Quelle ist ein USB-SDCardreader

    Ziele sind eine SSD Intern (copy-function) und eine USB-Festplatte (zip-funktion)
    Mein kompilierter Code ist auch in 64Bit


    Das ganze Kopieren und Zippen von 10GB Daten, eine Datei hat im Schnitt 25MB dauerte nun knapp 10 Minuten.

    Hier mein Code mit dem ich kopiere und zippe:
    Kann man das noch beschleunigen :?:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function DoFileZip() As Boolean
    2. Dim FiledateSuffix As String = Date.Now.ToString("-HH_mm")
    3. If Not Directory.Exists(propertyValues.TargetZipPath) Then Directory.CreateDirectory(propertyValues.TargetZipPath)
    4. RaiseEvent ZipFileReport(propertyValues.TargetZipPath & FiledateSuffix)
    5. Dim bufferSize As Integer = 1024 * 1024 ' 512 KB, die Größe anpassen
    6. Using zipToOpen As FileStream = New FileStream(propertyValues.TargetZipPath & FiledateSuffix & ".zip", FileMode.Create)
    7. Using archive As New ZipArchive(zipToOpen, ZipArchiveMode.Create)
    8. For Each file As String In Directory.GetFiles(propertyValues.SourcePath)
    9. Dim fileName As String = Path.GetFileName(file)
    10. Using sourceStream As New FileStream(file, FileMode.Open)
    11. Using entryStream As Stream = archive.CreateEntry(fileName).Open()
    12. Dim buffer(bufferSize - 1) As Byte
    13. Dim bytesRead As Integer
    14. Do
    15. bytesRead = sourceStream.Read(buffer, 0, bufferSize)
    16. If bytesRead > 0 Then
    17. entryStream.Write(buffer, 0, bytesRead)
    18. End If
    19. Loop While bytesRead > 0
    20. End Using
    21. End Using
    22. Next
    23. End Using
    24. End Using
    25. If Not System.IO.Directory.GetFiles(propertyValues.TargetZipPath).Length = 0 Then
    26. Else
    27. IO.Directory.Delete(propertyValues.TargetZipPath)
    28. End If
    29. Return True
    30. End Function
    31. Private Function DoFileCopy() As Boolean
    32. Dim NewSourcePath As New IO.DirectoryInfo(propertyValues.SourcePath)
    33. Dim file As IO.FileInfo
    34. If IO.Directory.Exists(propertyValues.TargetCopyPath) = False Then IO.Directory.CreateDirectory(propertyValues.TargetCopyPath)
    35. Dim bufferSize As Integer = 1024 * 1024 ' 512 KB, die Größe anpassen
    36. For Each file In NewSourcePath.GetFiles()
    37. RaiseEvent CopyFileReport(propertyValues.TargetCopyPath & "\" & file.Name)
    38. Using sourceStream As New FileStream(file.FullName, FileMode.Open)
    39. Using targetStream As New FileStream(propertyValues.TargetCopyPath & "\" & file.Name, FileMode.Create)
    40. Dim buffer(bufferSize - 1) As Byte
    41. Dim bytesRead As Integer
    42. Do
    43. bytesRead = sourceStream.Read(buffer, 0, bufferSize)
    44. If bytesRead > 0 Then
    45. targetStream.Write(buffer, 0, bytesRead)
    46. End If
    47. Loop While bytesRead > 0
    48. End Using
    49. End Using
    50. Next
    51. For Each subdir In NewSourcePath.GetDirectories()
    52. Call SubfolderCopy(subdir.FullName, propertyValues.TargetCopyPath & "\" & subdir.Name, True, bufferSize)
    53. Next
    54. Return True
    55. End Function
    56. Private Sub SubfolderCopy(ByVal SubSource As String, ByVal Destination As String, ByVal Overwrite As Boolean, ByVal bufferSize As Integer)
    57. Dim subdir As IO.DirectoryInfo
    58. Dim diSubSource As New IO.DirectoryInfo(SubSource)
    59. Dim file As IO.FileInfo
    60. If IO.Directory.Exists(Destination) = False Then IO.Directory.CreateDirectory(Destination)
    61. For Each file In diSubSource.GetFiles()
    62. RaiseEvent CopyFileReport(file.FullName)
    63. Using sourceStream As New FileStream(file.FullName, FileMode.Open)
    64. Using targetStream As New FileStream(Destination & "\" & file.Name, FileMode.Create)
    65. Dim buffer(bufferSize - 1) As Byte
    66. Dim bytesRead As Integer
    67. Do
    68. bytesRead = sourceStream.Read(buffer, 0, bufferSize)
    69. If bytesRead > 0 Then
    70. targetStream.Write(buffer, 0, bytesRead)
    71. End If
    72. Loop While bytesRead > 0
    73. End Using
    74. End Using
    75. Next
    76. For Each subdir In diSubSource.GetDirectories()
    77. Call SubfolderCopy(subdir.FullName, Destination & "\" & subdir.Name, Overwrite, bufferSize)
    78. Next
    79. End Sub

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Geschwindigkeits Unterschiede
    Wovon?
    Meinst Du beim Kopieren?
    Da sollte es keine geben.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Amelie schrieb:

    Kann man das noch beschleunigen


    Da musst du mal schauen. Du liest von einem SD-Card-Reader, wie schnell ist die Lesegeschwindigkeit von der Karte und/oder Reader? Wenn schlecht, besorg eine schnellere. Auf die SSD kopieren sollte schnell gehen, hängt natürlich von der Lesegeschwindigkeit der Quelle ab. Auf eine USB-HDD zu schreiben, da hängt es von der Verbindung ab, solltest du da mit nur z.B. 40MB/s schreiben können, wobei bei HDD ca. 200MB/s sein sollten, kannste mal den USB Port wechseln, jenachdem was du da für USB-Schnitstellen hast, du hast ja schon ein recht altes System.

    Wenn langsames schreiben der Flaschenhals sein sollte, versuch das ZIP stark zu komprimieren, so kannste durch CPU-Leistung schreibzeit sparen, weil weniger zu schreiben. Wie viel das dann bringt, hängt aber auch davon ab, wie stark man die Daten komprimieren kann.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    @RodFromGermany

    Zur Frage 1: Ich las, das generell die Code / Programmausführung bei beiden Sprachen ähnlich schnell sein soll. Also das C# da gar keinen Vorteil hätte.

    @DTF
    Es sind alles USB 2 Schnittstellen. Die externe HDD ist aber USB3 und die SSD ist recht neu. Aber ja ein insgesamt altes System. :)
    Die SD-Karte ist aber eine sehr schnelle 170MB/sec. und die Daten sind Kamera RAWs.

    Insgesamt geht es eigentlich darum, ob man den Code noch bzgl des copy/zip beschleunigen kann. Der Code vor meinem verbessern hatte z.B. noch kein Buffer usw. Damit, also mit dem Buffer, habe ich schon ca. 30% bessere Geschwindigkeit erreicht.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Also das C# da gar keinen Vorteil hätte.
    So isses. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Directory.EnumerateFiles & Directory.EnumerateDirectories könnte bei 10 Gig noch etwas raus holen.

    MSDN schrieb:


    The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names before the whole collection is returned; when you use GetFiles,
    you must wait for the whole array of names to be returned before you
    can access the array. Therefore, when you are working with many files
    and directories, EnumerateFiles can be more efficient.