TGViewer
AI-Driven Development. Родион Мостовой AI-Driven Development. Родион Мостовой @ai_driven · 5.5K subscribers
Post #47 987
o1-pro: Реализуем Parallel.ForEachAsync с регулируемым "на лету" параллелизмом

Не все знают, но в .NET начиная с 6-й версии есть прекрасный метод Parallel.ForEachAsync, который позволяет распараллелить задачу на заданное количество воркеров. По умолчанию выполнение происходит на тредпуле, поэтому в случае использования асинхронных методов некоторые задачи можно решать в десятки, а то и в сотни раз быстрее.
Одна из таких задач - это, например, генерация embeddings или любые другие обращения к облачной LLM или даже парсинг. Это здорово работает, но иногда возникает необходимость изменять количество воркеров (degree of parallelism) "на лету" - к примеру, в зависимости от пропускной способности LLM провайдера. Написать такую реализацию DynamicParallel.ForEachAsync самому, конечно, можно, но делать это нужно максимально внимательно с учетом всяких возможных дедлоков и race condition.
Делегировать эту задачу LLMке я порываюсь еще с сентября, но тогда ни GPT-4o, ни Sonnet 3.5 ни в какую не могли с этим справиться, хотя бы даже частично.

Шаги к решению
1. Итак, я попросил o1-pro сначала реализовать решение, позволяющее динамически регулировать параллелизм на лету. После примерно 5-ти минут раздумий, она выбрала решение на основе SemaphoreSlim (из цепочки рассуждений было видно, что так же в серьез рассматривалось решение с DataFlow, но в итоге было отметено ну и хорошо)
2. Затем, понимая комплексность задачи (многопоточный код жеж), я попросил Claude Sonnet 3.5 и обычную o1 поревьюить результат (ревью от Клода там во втором моем сообщении) - они нашли какие-то проблемы, на первый взгляд мне они показались адекватными и я правки принял.
3. Взял результат из шага 2, и попросил o1-pro на базе DynamicConcurrencyLimiter реализовать метод DynamicParallel.ForEachAsync. И тут важно отметить, что для упрощения нейросети задачи, я добавил ей в контекст исходник оригинального Parallel.ForEachAsync из актуальных сорсов .NET (оригинальный ForEachAsync НЕ поддерживает динамический параллелизм). Кстати, обратите внимание, что промпты в моих сообщениях довольно простые (для reasoning моделей это ок).
4. [важнейший шаг] Я попросил o1-pro написать тесты на получившиеся классы.

Про валидацию решения
Валидация сгенерированного кода тестами - это эдакий лайф-хак, особенно на случай когда код получается реально сложный и его трудно проверить глазами - тут уже важно, чтобы программист имел понимание возможных уязвимых мест разного сложного кода и всевозможных corner cases - в принципе, этот этап тоже можно практиковать совместно с LLM, но я бы все равно рекомендовал взять минутку и продумать какие-то сложные сценарии, которые должны быть покрыты. Возвращаюсь к нашему кейсу мне показалось важным убедиться в 3-х вещах:
1. В том, что при активной динамической регулировке параллелизма не возникает дедлоков (не хотелось бы где-то встрять навечно).
2. В том, что все элементы действительно обрабатываются.
3. В том, что каждый элемент списка обрабатывается ровно один раз.
Поэтому, я сам спроектировал еще один дополнительный стресс-тест, который делает все эти вещи. В этом тесте сейчас 1M элементов - но когда речь идет о проверке потокобезопасности, этого может быть мало для надежного теста, больше того, по-хорошему подобные решения еще имеет смысл прогонять на разных архитектурах (x86, arm, ...), т. к. из-за различий в модели памяти поведение многопоточного кода может слегка отличаться. Кстати, здесь бывает полезным погонять тесты в цикле до провала (в течение дня, например) - в Rider для этого есть опция Run Unit Tests Until Failure.

Что в итоге?
После пары косметических правок (в тестах было 2 ошибки компиляции), к моему удивлению, все тесты прошли с первого раза. Код и тесты тут.
Продолжение.
  • ❤ 7
  • 👍 4
More from @ai_driven
  1. Sep 27, 2026Vibe-Observability и автономный баг-фиксинг Эксперементирую с автономным исправлением баго…
  2. Sep 22, 2026Выступление за выступлением. Примерно так проходит для меня сентябрь. Много знакомств, инт…
  3. Sep 22, 2026Чем мой оркестратор отличается от claude -p и т. п.? Помимо полезных инструкций, вправляющ…
  4. Sep 21, 2026Вот за что люблю очередь сообщений в Codex. Накидываешь задачи на ночь одну за другой и со…
  5. Sep 18, 2026Ребят, на всякий случай уточню для тех, кто не вчитался - по 20$ подписке до 10 октября Де…
  6. Sep 18, 2026Post #293
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →