Мне было поручено переписать некоторые библиотеки, написанные на C #, чтобы после завершения запуска не было выделений.
Я только что попал в один проект, который каждые 30 секунд выполняет несколько запросов к БД через OdbcConnection. Я всегда просто использовал .ExecuteReader (), который создает OdbcDataReader. Существует ли какой-либо шаблон (например, шаблон сокета SocketAsyncEventArgs), который позволяет повторно использовать собственный OdbcDataReader? Или какой-то другой умный способ избежать выделения?
Я не удосужился изучить LINQ, поскольку все работающие базы данных основаны на Oracle, и, в последний раз, когда я проверял, не было официального поставщика Linq To Oracle. Но если есть способ сделать это в Linq, я мог бы использовать один из сторонних.
Обновление:
Я не думаю, что я четко указал причины требования no-alloc. У нас запущен один критический поток, и очень важно, чтобы он не зависал. Это приложение для торговли почти в реальном времени, и мы видим до 100 мс замораживания для некоторых коллекций второго поколения. (Я также слышал об играх, написанных таким же образом на C #). Существует один фоновый поток, который выполняет некоторую проверку соответствия и запускается каждые 30 секунд. Это делает запрос БД прямо сейчас. Запрос выполняется довольно медленно (около 500 мс для возврата со всеми данными), но это нормально, поскольку он не мешает критическому потоку. За исключением случаев, когда рабочий поток выделяет память, он вызывает GC, которые замораживают все потоки.
Мне сказали, что все библиотеки (включая эту) не могут выделять память после запуска. Согласен я с этим или нет, это требование от людей, которые подписывают чеки:).
Теперь, очевидно, есть способы, которыми я мог бы вводить данные в этот процесс без выделения ресурсов. Я мог бы настроить другой процесс и подключить его к этому с помощью сокета. Новые сокеты .NET 3.5 были специально оптимизированы, чтобы вообще не выделяться, используя новый шаблон SocketAsyncEventArgs. (На самом деле, мы используем их для подключения к нескольким системам и никогда не видим из них GC.) Затем создайте предварительно выделенный байтовый массив, который читает данные из сокета и просматривает данные, не выделяя при этом никаких строк. (Я не знаком с другими формами IPC в .NET, поэтому я не уверен, выделяют ли отображаемые в памяти файлы и именованные каналы или нет).
Но если есть более быстрый способ выполнить этот запрос без выделения ресурсов без прохождения всех этих хлопот, я бы предпочел его.