rapide déplacement des données à partir d'un fichier de quelques StringIO
En Python, j'ai un fichier de flux, et je veux copier une partie de celui-ci dans un StringIO
. Je veux que ce soit le plus rapide possible, avec un minimum de copie.
Mais si je fais:
data = file.read(SIZE)
stream = StringIO(data)
Je pense que 2 exemplaires a été fait, non? Une copie des données à partir d'un fichier, d'un autre exemplaire à l'intérieur de StringIO
en mémoire tampon interne. Puis-je éviter que l'une des copies? Je n'ai pas besoin temporaire data
, donc je pense que l'un exemplaire doit être assez
Qu'allez-vous faire avec
Êtes-vous à l'aide de Python 2.x ou 3.x?
Je veux lire et le modifier aussi. La question est d'ordre général à propos de Python, si il ya une différence entre les 2.x et 3.x veuillez dire
stream
? Le lire??Êtes-vous à l'aide de Python 2.x ou 3.x?
Je veux lire et le modifier aussi. La question est d'ordre général à propos de Python, si il ya une différence entre les 2.x et 3.x veuillez dire
OriginalL'auteur zaharpopov | 2011-11-23
Vous devez vous connecter pour publier un commentaire.
En bref: vous ne pouvez pas éviter de 2 copies à l'aide de StringIO.
Certaines hypothèses:
file.read(SOME_BYTE_COUNT)
si votre fichier est binaire.Réponse longue: Depuis python chaînes sont immuables et la StringIO tampon n'est pas, une copie devra être fait tôt ou tard; sinon, vous seriez la modification d'un objet immuable! Pour ce que vous voulez être possible, le StringIO objet aurait besoin d'avoir une méthode spécifique que lire directement à partir d'un fichier de l'objet donné en argument. Il n'y a pas une telle méthode.
À l'extérieur de StringIO, il existe des solutions qui permettent d'éviter la copie supplémentaire. Sur le dessus de ma tête, cela va lire un fichier directement dans une modifiables tableau d'octets, aucune copie supplémentaire:
Il peut être difficile à utiliser, en fonction de l'utilisation que vous souhaitez, puisque c'est un tableau de valeurs de 0 à 255, et non pas un tableau de caractères. Mais il est fonctionnellement équivalent à un StringIO objet, et à l'aide de
np.fromstring
,np.tostring
,np.tofile
et de tranchage notation devrait vous rendre où vous voulez. Vous pourriez aussi avoir besoinnp.insert
,np.delete
etnp.append
.Je suis sûr qu'il ya d'autres modules qui vont faire des choses similaires.
TIMEIT:
Combien tout cela vraiment question? Eh bien, voyons. J'ai fait un fichier de 100 mo,
largefile.bin
. Puis, j'ai lu dans le fichier en utilisant les deux méthodes et de modifier le premier octet.Donc dans mon cas, à l'aide de StringIO est de 50% plus lent que d'utiliser numpy.
Enfin, pour la comparaison, en éditant directement le fichier:
Donc, c'est près de 4500 fois plus rapide. Bien sûr, il est extrêmement dépendante de ce que vous allez faire avec le fichier. Modifier le premier octet est guère représentative. Mais en utilisant cette méthode, vous avez une longueur d'avance sur les deux autres, et puisque la plupart des systèmes d'exploitation ont une bonne mise en mémoire tampon de disques, la vitesse peut être très bon aussi.
(Si vous n'êtes pas autorisé à éditer le fichier et ainsi de vouloir éviter le coût d'une copie de travail, il ya un couple de façons possibles pour augmenter la vitesse. Si vous pouvez choisir le système de fichiers, Btrfs a un copy-on-write opération de copie de fichier -- le fait que l'acte de prendre une copie d'un fichier pratiquement instantanée. Le même effet peut être obtenu à l'aide d'un LVM instantané de tout système de fichiers.)
Pas que je sache, non. Bytearray semble ne pas accepter les objets de fichier comme argument.
qui sonne comme une honte, donc la seule façon de lire modifiables tampon à partir d'un fichier rapide est avec numpy 🙁
Le plus rapide serait de modifier directement le fichier (ou une copie) à l'aide de l'objet fichier méthodes
seek
,read
etwrite
-- la même interface que StringIO. Le cache disque permettra d'accélérer les choses. Est-il une raison pour laquelle vous voulez qu'il en mémoire?si il y a beaucoup de traitement à faire sur les données, je ne suis pas sûr que ce serait plus rapide pour le garder dans le fichier. Aussi, je ne veux pas modifier le contenu du fichier lui-même (mais éventuellement générer des rapports à un autre fichier)
OriginalL'auteur Lauritz V. Thaulow
Non, il n'est pas une copie supplémentaire effectué. Le tampon utilisé pour stocker les données est le même. Les deux
data
et les attributs internes accessibles à l'aide deStringIO.getvalue()
sont des noms différents pour les mêmes données.Un rapide de parcourir la source montre que
cStringIO
ne pas en faire une copie sur une construction, mais elle permet de faire une copie sur l'appel decStringIO.getvalue()
, donc je ne peux pas répéter la démonstration ci-dessus.data
est immuable et le contenu destream
n'est pas, la copie supplémentaire est lié à être effectué dès que les StringIO objet est modifié, si ce n'est avant. La question demeure.C'est une autre question. Si vous voulez savoir comment StringIO œuvres, la meilleure chose à faire est de lire
StringIO.py
.merci, mais je suis particulièrement intéressé par cette copie faite lors de la modification est effectuée. Je sais que StringIO t-il, ma question est de savoir comment éviter d'identité. Comment lire les données directement à partir d'un fichier modifiable StringIO?
OriginalL'auteur Michael Hoffman
Peut-être ce que vous cherchez est un tampon/memoryview:
De cette façon, vous pouvez accéder à une tranche de l'origine des données sans le copier. Cependant, vous devez être intéressé à accéder à ces données uniquement dans l'octet de format puisque c'est ce que le protocole de mémoire fournit.
Vous pouvez trouver plus d'informations en ce qui concerne question.
Edit: Dans ce post de blog j'ai trouvé par le biais de reddit, certains de plus amples renseignements sont donnés sur le même problème:
Selon l'auteur, aucune copie supplémentaire est créé et les données peuvent être modifiées depuis
bytearray
est mutable.Il dépend de l'objet en cours d'accès. Dans le memoryview la documentation il y a un exemple qui modifie une valeur dans un
bytearray
objet (sans changer sa taille). Cependant, dans votre exemple,file.read
sera de retour une inmutable stringinmutable, donc vous ne serez pas en mesure de le faire sur cet objet.Je viens de le voir ceci dans reddit et il semble résoudre le problème à obtenir les données dans un
bytearray
à l'aide defile.readinto
.OriginalL'auteur jcollado
Le fichier peut être binaire...
OriginalL'auteur Jakob Bowyer