9
votes

La meilleure façon de gérer une liste avec des éléments changeants

Voici la situation:
J'ai la liste des cordes de magasin qui sont en réalité des chiffres et peuvent devenir assez gros (des centaines de millions d'articles).
Je stocke les numéros en tant que chaîne, car il existe une option pour afficher certaines informations supplémentaires qui sont du texte.

Parce que cela prend beaucoup de mémoire à stocker, j'ai décidé que je ne stockerai que 5 millions d'articles maximum. (Cela ne prendra que environ 250-300 Mo). P>

La liste est remplie par la sortie d'un calcul. Si un numéro est trouvé, il sera ajouté à la liste, ce numéro est toujours plus grand que les éléments existants. P>

Lorsque la liste a atteint 5 mil, je souhaite supprimer le premier élément et ajouter le nouvel élément à la Liste. p>

J'aime: p> xxx pré>

Comme vous pouvez lire dans le commentaire, c'est très très lent très lent. Il suffit de réduire mes performances de 15 fois. Où il a fallu 2 minutes, il faut maintenant environ 30. P>

J'ai essayé quelques choses avec Linq comme .skip (1) .toliste code> mais qui recréera la liste et est donc même plus lent. p>

La liste doit rester dans le bon ordre, donc écraser par l'index n'est pas une option (sauf si vous ne pouvez expliquer un bon travail autour). P>

Ma question: Y a-t-il une manière décente de faire cela? strong> p>

J'ai vraiment besoin de la performance ici, car il peut être nécessaire de vérifier environ 1000000000000 numéros. Cela peut prendre une journée de siècle, mais un mois est un peu trop: (. P>

besoin d'informations supplémentaires, n'hésitez pas à demander, je serai heureux de fournir. P>

Solution: strong>
Ceci effectue O (1) P>

    // Set the _result
    Queue<object> _result = new Queue<object>(5000000);

    /// Inside the method
    // If the count has reach it's max, dequeue the first item
    if (_result.Count == 5000000)
        _result.Dequeue();
    _result.Enqueue(result);


2 commentaires

Y a-t-il une raison convaincante que vous devez utiliser une liste? Pouvez-vous utiliser une base de données SQLite à la place


@ user1556110 L'application doit pouvoir fonctionner sur n'importe quel ordinateur et en mémoire, je ne sais pas si cela est possible dans SQLite.


5 Réponses :


1
votes

Je vais vous suggérer de mieux mettre en œuvre une file d'attente circulaire. Ensuite, vous poussez tous les Int à la fin de la file d'attente et lorsque vous manquez d'espace (déterminé par la taille fixe), chaque opération nécessitera de faire sauter la première et poussez sur le fond. O (1) .

Advantage vs. Array est que vous ne préventions pas de l'espace avant que ce soit nécessaire. Mais, en dernier lieu, considérez vraiment pour stocker des intents comme, eh bien, int. Peu importe les opérations que vous effectuerez, vous devez toujours stocker des nombres comme des chiffres.


5 commentaires

Suggérez-vous alors que je devais garder deux tableaux, un pour les chiffres et l'autre pour que l'utilisateur souhaite des informations supplémentaires?


Non, je ne suggère même pas que les tableaux utilisent. Ce que je vous encourage à penser, c'est si vous avez vraiment besoin d'avoir les informations supplémentaires avec vos entiers. Si tel est le cas, bon, sinon, si vous pouvez dire calculer les informations en fonction du numéro, stockez simplement le numéro.


Merci pour l'indice, je verrai ce qui est possible.


Je serais en désaccord que vous devriez toujours stocker des nombres comme des chiffres, si vous ne faites pas de mathématiques et que vous n'avez pas besoin de la mémoire, stockez des chiffres, car les chaînes peuvent éviter les problèmes de dimensionnement.


@Guvante Bien sûr pour ces cas, mais comme l'op de l'OP ", l'application doit pouvoir exécuter n'importe quel ordinateur et en mémoire" Je ne ferai aucune garantie de mémoire si elle doit être exécutée sur une consommation, mieux à être humble. De plus, mieux être préparé pour l'extensibilité.



0
votes

Pourquoi ne prévenez-vous pas le tableau et avez deux entiers, indiquant le début et la fin de la matrice. Évidemment, ils tiennent tous les deux égaux à 0. Une fois que vous avez manqué de pièce, vous venez de commencer à envelopper.

Exemple PSEDEO HELPER CLASSE: P>

class CircularArray
{
  const int maxSize = 5000000;
  private int[] arr = new int[maxSize];
  private int start = 0;
  private int end = 0;

  public void Add(int value)
  {
    int newEnd = (end + 1) % maxSize;
    if (newEnd == start)
      start = (start + 1) % maxSize;
    end = newEnd;
    arr[end] = value;
  }

  public int Get(int index)
  {
    int newIndex = (start + index) % maxSize;
    return arr[newIndex];
  }
}


0 commentaires

4
votes

Avez-vous déjà des articles de réorganisation? Si vous ne le faites pas, une file d'attente circulaire fonctionnerait assez bien.

System.Collections.Generic.Queue est un, je viens de vérifier.

pour développer les avantages d'une file d'attente, c'est le removeat implémentation (grossièrement): xxx

car list [0] est toujours le premier élément, vous devez Tout déplacer pour supprimer le premier élément.

En revanche, une file d'attente suit le premier élément séparément. Cela modifie le code ci-dessus à ceci: xxx


3 commentaires

Merci pour l'espace de noms, je vais vérifier :).


En fait, je réorganise les articles d'une manière ou d'une autre. Je vais inverser la liste à la fin, mais il est facile de omettre cela.


Merci beaucoup! Cela a fait l'affaire, je posterai ma solution dans la question.



0
votes

Lorsque vous retirez le premier élément d'une arracheListe, tous les autres éléments sont décalés. Un Québec Circular vous permettrait de conserver l'ordre d'origine et d'éliminer les changements de consommation de temps qui se produisent lorsque vous supprimez la tête de la liste.


0 commentaires

0
votes

peut être LinkedList Classe < / a> peut vous aider? La suppression et l'ajout aux deux extrémités est O (1) opération, mais l'itération sera O (n), ou si vous avez besoin de O (1) sur l'accès possible, vous pouvez utiliser dictionnaire ou trioddiction Une autre mise en œuvre personnalisée est QueueDictionary , je l'ai utilisée lorsque j'ai besoin d'une opération O (1) sur l'ajout et la suppression à la fin ou à la mise en route (file d'attente / dequue) et à accéder à une valeur. Questionnaires ici: Comment puis-je implémenter une queue, une combinaison de file d'attente et de dictionnaire en C #?


0 commentaires