Articles

Verschil tussen `open` en `io.BytesIO` in binaire streams

Om het eenvoudig te houden, laten we voor nu schrijven in plaats van lezen beschouwen.

Dus als je open() gebruikt zoals bijvoorbeeld:

with open("test.dat", "wb") as f: f.write(b"Hello World") f.write(b"Hello World") f.write(b"Hello World")

Na het uitvoeren van dat zal een bestand genaamd test.dat worden aangemaakt, met daarin 3x Hello World. De gegevens worden niet in het geheugen bewaard nadat ze naar het bestand zijn geschreven (tenzij ze bij een naam worden bewaard).

Nu, als je io.BytesIO() in plaats daarvan overweegt:

with io.BytesIO() as f: f.write(b"Hello World") f.write(b"Hello World") f.write(b"Hello World")

Wie in plaats van de inhoud naar een bestand te schrijven, wordt het naar een buffer in het geheugen geschreven. Met andere woorden een stuk RAM. In wezen zou het volgende schrijven het equivalent zijn:

buffer = b""buffer += b"Hello World"buffer += b"Hello World"buffer += b"Hello World"

In relatie tot het voorbeeld met het with statement, dan zou er aan het eind ook een del buffer staan.

Het belangrijkste verschil hier is optimalisatie en performance. io.BytesIO is in staat om een aantal optimalisaties uit te voeren waardoor het sneller is dan simpelweg alle b"Hello World" een voor een aan elkaar te plakken.

Om het te bewijzen hier een kleine benchmark:

  • Concat: 1,3529 seconden
  • BytesIO: 0.0090 seconden
import ioimport timebegin = time.time()buffer = b""for i in range(0, 50000): buffer += b"Hello World"end = time.time()seconds = end - beginprint("Concat:", seconds)begin = time.time()buffer = io.BytesIO()for i in range(0, 50000): buffer.write(b"Hello World")end = time.time()seconds = end - beginprint("BytesIO:", seconds)

Naast de prestatiewinst heeft het gebruik van BytesIO in plaats van concatenating het voordeel dat BytesIO kan worden gebruikt in plaats van een bestandsobject. Dus stel dat je een functie hebt die een bestandsobject verwacht om naar te schrijven.

Het verschil is dat open("myfile.jpg", "rb") gewoon de inhoud van myfile.jpg laadt en teruggeeft; terwijl BytesIO weer gewoon een buffer is met wat gegevens.

Omdat BytesIO slechts een buffer is – als je de inhoud later naar een bestand zou willen schrijven – zou je het volgende moeten doen:

buffer = io.BytesIO()# ...with open("test.dat", "wb") as f: f.write(buffer.getvalue())

Ook heb je geen versie genoemd; ik gebruik Python 3. Met betrekking tot de voorbeelden: Ik gebruik het with statement in plaats van het aanroepen van f.close()

Laat een antwoord achter

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *