J'ai une application .NET écrite en C# (.NET 4.0). Dans cette application, nous devons lire un grand ensemble de données à partir d'un fichier et afficher le contenu dans une structure semblable à une grille. Donc, pour ce faire, j'ai placé un DataGridView sur le formulaire. Il a 3 colonnes, toutes les données de la colonne proviennent du fichier. Initialement, le fichier contenait environ 600 000 enregistrements, correspondant à 600 000 lignes dans DataGridView.Traitement de très grands ensembles de données et chargement juste à temps
J'ai rapidement découvert que DataGridView se replie avec un ensemble de données aussi volumineux, donc j'ai dû passer en mode virtuel. Pour ce faire, j'ai d'abord lu le fichier complètement dans 3 tableaux différents (correspondant à 3 colonnes), puis l'événement CellValueNeeded se déclenche, je fournis les valeurs correctes des tableaux.
Cependant, il peut y avoir un énorme (ÉNORME!) Nombre d'enregistrements dans ce fichier, comme nous l'avons rapidement découvert. Lorsque la taille de l'enregistrement est très grande, lire toutes les données dans un tableau ou dans une liste <>, etc., ne semble pas réalisable. Nous rencontrons rapidement des erreurs d'allocation de mémoire. (Exception de mémoire insuffisante)
Nous sommes restés coincés là, mais nous nous sommes alors rendu compte, pourquoi lire les données tout d'abord dans les tableaux, pourquoi ne pas lire le fichier à la demande lorsque l'événement CellValueNeeded se déclenche? Donc, c'est ce que nous faisons maintenant: Nous ouvrons le fichier, mais ne lisons rien, et comme les événements CellValueNeeded se déclenchent, nous cherchons d'abord Seek() à la position correcte dans le fichier, puis lisons les données correspondantes.
C'est le meilleur que nous puissions trouver, mais, tout d'abord, c'est assez lent, ce qui rend l'application léthargique et pas facile à utiliser. Deuxièmement, nous ne pouvons nous empêcher de penser qu'il doit y avoir un meilleur moyen d'y parvenir. Par exemple, certains éditeurs binaires (comme HXD) sont incroyablement rapides pour n'importe quelle taille de fichier, alors j'aimerais savoir comment cela peut être réalisé. Oh, et pour ajouter à nos problèmes, en mode virtuel de DataGridView, lorsque nous définissons RowCount sur le nombre de lignes disponibles dans le fichier (par exemple 16.000.000), il faut un certain temps pour que DataGridView s'initialiser. Des commentaires pour ce "problème" seraient également appréciés.
Merci
Bonjour Jim, T, est un struct avec 4 flotteurs double précision. Donc, 4 * 8 * 16M = 512 Mo de données. – SomethingBetter
J'ai essayé d'utiliser .NET MemoryMappedFile, mais dès que vous créez une vue, il essaie apparemment de charger le fichier en mémoire, car j'ai des exceptions de mémoire insuffisante. Je pensais que MemoryMappedFile segmenterait en interne les accès aux données en pages et ne chargerait que les pages requises en mémoire. – SomethingBetter
@SomethingBetter: Je suppose que 512 Mo est un problème si vous êtes sur une machine 32 bits. Si vous utilisez un fichier mappé en mémoire, vous souhaiterez afficher votre fichier dans un fichier plus petit que la taille totale du fichier. Ensuite, vous ajustez votre vue en tant que pages de l'utilisateur à travers les données. –