Подтвердить что ты не робот

Насколько масштабируемо LINQ?

Недавние беседы с коллегами дали различные точки зрения по этому вопросу. Что вы говорите, члены SO?

Я знаю, что даже понятие масштабируемости может быть принято во множестве разных способов и контекстов, но это было частью обсуждения, когда это произошло. Кажется, что каждый из нас по-другому понимает, что такое масштабируемость. Мне любопытно увидеть, что здесь все меняется. Фактически, я разместил question только для этой концепции.

4b9b3361

Ответ 1

Я бы предположил, что лучший способ проверить - написать тесты, но, на мой взгляд, у LINQ есть возможность для оптимизаций, которые нет в ручном написании аналогичного кода. Я не знаю, насколько хорошо он использует их.

LINQ позволяет вам выражать то, что вы хотите, а не как его генерировать. Одним очевидным преимуществом является то, что LINQ автоматически распараллеливается (см. PLINQ).

Другим преимуществом LINQ является то, что он ленив, поэтому вы можете выполнять вычисления, извлекать из коллекции по мере необходимости. Вы можете скомпоновать эквивалент, но в LINQ может быть намного проще.

Ответ 2

В тестах, которые мы сделали, LINQ для объектов (ForEach) был примерно в 2 раза медленнее, чем цикл foreach.

LINQ to SQL (база данных MS SQL) почти 10x медленнее, чем прямой запрос с использованием устройства чтения данных, используя большую часть времени, создавая SQL из дерева выражений (так что вы будете связаны с ЦП и базой данных будет холостым) Чтобы этого избежать, вы должны использовать скомпилированные запросы.

Подробнее см. в этом. Большая часть информации в сообщении все еще действительна с .NET 3.5 SP1.

Ответ 3

Этот вопрос немного напоминает вопрос: "Насколько масштабируемы коллекции?"

Позвольте просто поговорить о LINQ для объектов. Вообще говоря, в той степени, в которой большинство реализаций IEnumerable<T> итерации по каждому элементу базовой коллекции, LINQ имеет большой потенциал для плохого масштабирования. Создайте List<Foo>, который содержит десять миллионов элементов и что-то вроде этого:

var list = from Foo f in fooList
           where f.Value = "Bar"
           select f;

будет медленным. Но это действительно не ошибка LINQ. Это тот, который дал ему список из десяти миллионов предметов.

Вы справляетесь с этим так же, как и с ним, если LINQ не существует: путем создания словарей и SortedLists и т.п., которые помогут вам скрыть пространство поиска.

LINQ может улучшить масштабируемость (что облегчает задачу масштабирования) с помощью отложенного выполнения запроса. Вы можете заменить наивный метод, который создает список, фильтрует его в новый список, фильтрует его в новый список и т.д. С помощью ряда запросов LINQ:

var list1 = from Foo f in fooList where f.Value1 = "Bar" select f;
var list2 = from Foo f in list1 where f.Value2 = "Baz" select f;
var list3 = from Foo f in list2 where f.Value3 = "Bat" select f;

все из которых выполняются за один проход через базовую коллекцию, когда (и if) становится необходимым перебирать окончательный список. Опять же, это ничего нового: если бы у вас не было LINQ, вы, вероятно, в конечном итоге заменили бы ваш наивный метод тем, который сделал то же самое. Но LINQ делает это намного проще.

Ответ 4

По моему мнению, LINQ предназначен для упрощения работы с точки зрения разработки, а не для решения проблемы масштабируемости.

Фактически, использование LINQ упрощает работу, скрывая множество осложнений под обложками, и это может привести к безответственному использованию проблем масштабируемости.

Примеры изобилуют другими ответами, но упоминаются наиболее значимые:

  • Если вы запрашиваете коллекцию объектов, вы не можете игнорировать ее размер. Возможно, делать это в модели с LINQ, звучало хорошо, когда было несколько объектов для запроса... но по мере роста размера становится очевидным, что запрос должен происходить в базе данных, а не в модели.

  • Если вы создаете автогенерирование SQL с помощью LINQ, насколько я знаю, вы не можете дать подсказки вашей базы данных о том, как компилировать запросы, например WITH (NOLOCK). По мере роста размеров таблиц необходимо решить эти проблемы.

  • Как и выше, но, возможно, более общий: когда вы решаете проблемы масштабируемости по БД, вы должны контролировать, что делает БД. Наличие языка, который компилируется в SQL, который затем снова компилируется в план выполнения, удаляет управление из ваших рук.

  • Что произойдет, если вам нужно изменить схему базы данных, чтобы сделать ее более масштабируемой, и ваш код сильно привязан к ней, потому что у вас нет хранимых процедур?

  • Хотя это кажется простым, вы не можете менять поставщика LINQ без большой боли: запрос SQL Server - это не то же самое, что запрос объекта или запрос XML. LINQ очень похож. Я ожидаю, что некоторые из моих младших разработчиков перейдут на "LINQ spree", потому что это легче, чем научиться делать вещи с учетом масштабируемости.

В заключение, я думаю, что можно написать масштабируемый код с LINQ, но только с его помощью с хорошим вниманием. Нет инструментов для убийц, только код убийцы.

Ответ 5

В значительной степени зависит от того, какой поставщик LINQ вы используете и как вы его используете. LINQ, вероятно, не знает об удивительной скорости выполнения, но скорее предоставляет разработчикам значительно лучшую производительность.

В соответствии с эта ссылка даже с некоторыми из CTP Linq to SQL была уже лучше, чем использование прямого SQL в некоторых случаях.

Если вы заинтересованы в скорости и используете LINQ для объектов alot здесь - это проект codeplex (я думаю) для провайдера, который может дают вам 1000-кратное повышение производительности.

Ответ 6

Ваш вопрос о масштабируемости в некотором роде зависит от того, для чего вы используете LINQ for. В бизнес-приложениях вы не найдете много исполняемых команд SQL - они медленны и должны быть скомпилированы в СУБД. Вместо этого вы увидите много вызовов хранимых процедур. Они будут немного быстрее в LINQ.

Имейте в виду, что LINQ to SQL и т.д. построены на TOP ADO.NET - это не совсем другая методология или что-то еще. Конечно, LINQ to XML будет использовать разные API-интерфейсы под обложками. Это будет очень похоже на компилятор - всегда есть оптимизация, которую люди могут сделать быстрее, но, по большей части, эти API будут способны генерировать более быстрый и менее ошибочный код, чем код, который вы пишете сами.

С точки зрения масштабирования вы всегда можете поместить LINQ за веб-службу, если хотите немного распределить свои данные или использовать репликацию SQL-сервера. Он не должен быть менее масштабируемым, чем ADO.NET.

Ответ 7

Масштабируемость и производительность - это две разные, но связанные вещи. Если вы хотите измерить производительность, вам нужно посмотреть, сколько пользователей (например) вы можете поддерживать с помощью одного окна. Когда вы измеряете масштабируемость, вы добавляете еще одну ячейку и видите, можете ли вы удвоить первоначальную сумму? Скорее всего, и вы можете добавить только 75% к своей мощности обработки, а затем добавляет только 50% исходного блока, и, таким образом, он быстро снижается до нуля. Независимо от того, сколько ящиков вы добавляете с такой скоростью, вам повезло удвоить количество поддерживаемых пользователей. Эта масштабируемость.

Как ваши весы модуля Linq, вероятно, зависят больше от базы данных, насколько мощной является машина, какова конструкция базы данных, какова конструкция вашего приложения.

Вы часто видите микро-тесты, которые, как предполагается, показывают что-то убедительное, но они никогда не делают, потому что они всего лишь ключевое отверстие для всей проблемы.

Вы можете найти хороший старый пример 20/80. Это, вероятно, 20% от инструмента и 80% от всех видов материальных благ, которые составляют ваше приложение.

Ответ 8

Если вы ищете пример реальной жизни, stackoverflow сильно использует Linq, проверьте этот пост/подкаст.

Ответ 9

Существует цена для кэширования и загрузки объектов по требованию с использованием инфраструктуры Linq to SQL. Если объект может требовать ленивую загрузку частей по требованию, очень вероятно, что в каждом объекте есть ссылка на контекст данных. Кстати, этот контекст данных также кэширует каждый объект, запрашиваемый у него. Это означает, что если вы держите одну из своих объектов (либо в кеше, либо просто потому, что используете ее позже), вы не только держитесь за этот объект, но и каждый объект, когда-либо запрашиваемый контекстом данных. Они никогда не получат мусор, потому что они все еще ссылаются.

Это не проблема, если все ваши задачи имеют короткий срок службы, и приложение создает новые DataContexts каждый раз, когда оно выполняет новую работу. Но я вижу, как он может создавать проблемы с масштабируемостью, если кто-то не знал о дополнительном обременении вместе с каждым объектом.

Ответ 10

Linq во многих отношениях является масштабируемым.

Один из аспектов - это реализация спецификации linq, которая позволяет интерпретировать Expression для завершения процесса на другом языке (Linq2Sql, Linq2Hibernate) или в распределенном вычислительном окружении, таком как кластер с уменьшением карты (если это необходимо) DryadLINQ)

Другим аспектом является семантика, которую linq предоставляет языку. Вы можете выполнять итерацию через миллиарды объектов без заполнения коллекции в памяти, если ваш провайдер поддерживает отложенную загрузку, или вы можете парализовать или оптимизировать запрос (PLINQ или i4o).