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> 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 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: 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> .skip (1) .toliste code> mais qui recréera la liste et est donc même plus lent. p>
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);
5 Réponses :
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. 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. p> O (1) code>. p>
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é.
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];
}
}
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. P>
pour développer les avantages d'une file d'attente, c'est le car En revanche, une file d'attente suit le premier élément séparément. Cela modifie le code ci-dessus à ceci: p> removeat code> implémentation (grossièrement): p> list [0] code> est toujours le premier élément, vous devez Tout déplacer pour supprimer le premier élément. P>
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.
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. P>
peut être LinkedList dictionnaire code> ou trioddiction code>
Une autre mise en œuvre personnalisée est QueueDictionary Code>, 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 #? P>
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.