Voici un exemple simple pour illustrer mon problème : J'ai un grand fichier binaire avec 10 millions de valeurs.
Je veux obtenir les valeurs de 5K à partir de certains points de ce fichier.
J'ai une liste d'index qui me donne l'endroit exact dans le fichier où se trouve ma valeur.
Pour résoudre ce problème, j'ai essayé deux méthodes :
-
En passant par les valeurs et en utilisant simplement
seek()
(depuis le début du fichier) pour obtenir chaque valeur, quelque chose comme ceci :binaryFile_new = open(binary_folder_path, "r+b") for index in index_list: binaryFile_new.seek (size * (index), 0) wanted_line = binaryFile_new.read (size) wanted_line_list.append(wanted_line) binaryFile_new.close()
Mais si je comprends bien, cette solution lit depuis le début pour chaque index, donc la complexité est O(N**2) en termes de taille de fichier.
-
Trier les index pour pouvoir parcourir le fichier "une fois" tout en cherchant à partir de la position actuelle avec quelque chose comme ça :
binaryFile_new = open(binary_folder_path, "r+b") sorted_index_list = sorted(index_list) for i, index in enumerate(sorted_index_list): if i == 0: binaryFile_new.seek (size * (v), 0) else: binaryFile_new.seek ((index - sorted_index_list[i-1]) * size - size, 1) binaryFile_new.seek (size * (index), 0) wanted_line = binaryFile_new.read (size) wanted_line_list.append(wanted_line) binaryFile_new.close()
Je m'attendais à ce que la deuxième solution soit beaucoup plus rapide car, en théorie, elle parcourrait l'ensemble du fichier en une seule fois O(N).
Mais pour une raison quelconque, les deux solutions fonctionnent de la même manière.
J'ai également une contrainte forte sur l'utilisation de la mémoire, car j'exécute cette opération en parallèle et sur de nombreux fichiers, je ne peux donc pas lire les fichiers en mémoire.
Peut-être que le mmap
sera utile ? Cependant, je pense que mmap
balaie également l'ensemble du fichier jusqu'à l'index, il ne s'agit donc pas d'un "véritable" accès aléatoire.