On m'a confié la tâche de réécrire certaines bibliothèques écrites en C# afin qu'il n'y ait pas d'allocation une fois le démarrage terminé..NET DB requête sans allocations?
Je viens d'arriver à un projet qui fait des requêtes DB sur un OdbcConnection toutes les 30 secondes. J'ai toujours juste utilisé .ExecuteReader() qui crée un OdbcDataReader. Existe-t-il un modèle (comme le modèle de socket SocketAsyncEventArgs) qui vous permet de réutiliser votre propre OdbcDataReader? Ou une autre façon intelligente d'éviter les allocations?
Je n'ai pas pris la peine d'apprendre LINQ puisque tous les dbs au travail sont basés sur Oracle et la dernière fois que j'ai vérifié, il n'y avait pas de fournisseur Linq To Oracle officiel. Mais s'il y a un moyen de le faire dans Linq, je pourrais utiliser l'un des tiers.
Mise à jour:
Je ne pense pas que je spécifié clairement les raisons de l'exigence de non-alloc. Nous avons un thread critique en cours d'exécution et il est très important qu'il ne gèle pas. Ceci est pour une application de trading en temps quasi réel, et nous voyons un blocage de 100 ms pour certaines collections Gen 2. (J'ai aussi entendu parler de jeux écrits de la même manière en C#). Un thread d'arrière-plan effectue une vérification de conformité et s'exécute toutes les 30 secondes. Il fait une requête db en ce moment. La requête est assez lente (environ 500 ms pour revenir avec toutes les données), mais c'est correct car cela n'interfère pas avec le thread critique. Sauf si le thread de travail alloue de la mémoire, cela provoquera des GC qui gèlent tous les threads.
On m'a dit que toutes les bibliothèques (y compris celle-ci) ne peuvent pas allouer de mémoire après le démarrage. Que je sois d'accord ou non, c'est l'exigence des gens qui signent les chèques :).
Maintenant, il y a clairement des façons que je pourrais obtenir les données dans ce processus sans allocations. Je pourrais mettre en place un autre processus et le connecter à celui-ci en utilisant une socket. Les nouveaux sockets .NET 3.5 ont été spécifiquement optimisés pour ne pas être alloués du tout, en utilisant le nouveau pattern SocketAsyncEventArgs. (En fait, nous les utilisons pour se connecter à plusieurs systèmes et ne jamais voir de GC.) Ensuite, ayez un tableau d'octets pré-alloué qui lit à partir du socket et passe par les données, n'allouant aucune chaîne le long du chemin. (Je ne suis pas familier avec d'autres formes de IPC dans .NET, donc je ne suis pas sûr si les fichiers mappés en mémoire et les canaux nommés allouer ou non).
Mais s'il y a un moyen plus rapide d'obtenir cette requête sans allocation sans passer par tous les tracas, je préfère.
Toutes les 30 secondes ... vous remarquez que l'effet des allocations sur de si longues périodes est très, très faible. – Dykam
Hmm, pas d'allocations. Supprimez d'abord toutes les chaînes de vos tables DBase. Revenez quand vous avez terminé afin que nous puissions aborder les numéros 2 à 50. Vous devrez éventuellement passer en C++. –