Бенчмарк Linq2SQL, Subsonic2, Subsonic3 - Есть еще идеи, чтобы сделать их быстрее? - PullRequest
7 голосов
/ 02 марта 2010

Я работаю с Subsonic 2 уже более 3 лет ...

После появления Linq, а затем Subsonic 3 я начинаю думать о переходе на новые фьючерсы Linq, которые связаны с sql.

Я должен сказать, что я начинаю движение и портирую свою дозвуковую 2 с SubSonic 3, и очень скоро я обнаруживаю, что скорость была настолько низкой, что я не поверил - и начинаю все эти тесты.

Затем я тестирую Linq2Sql и вижу также задержку - сравните ее с Subsonic 2.

Мой вопрос здесь, особенно для linq2sql и предстоящей версии 4 для dotnet, что еще я могу сделать, чтобы ускорить его? Что еще в настройках или классах linq2sql, а не в этом коде, который я использовал для своих сообщений

Я размещаю здесь проект, в котором я делаю тесты, а также снимки экрана с результатами.

Как я делаю тесты - и точность моих измерений.

Я использую только для своего вопроса Google Chrome, потому что мне сложно показать здесь много других мер, которые я сделал с более сложными программами. Это самый простой, я просто измеряю данные прочитаны. Как я могу доказать это. Я делаю простой Thread.Sleep (10 секунд) и вижу, вижу ли я эти 10 секунд в Google Chrome Measure, и да, я вижу его.


(источник: planethost.gr )

вот еще тест с этой командой Sleep, чтобы увидеть, что на самом деле дает Chrome.

10 секунд задержки
100 мс задержка
Нулевая задержка

Есть только маленькие 15 мс, которые попадают в беспорядок, настолько малы, что сравнивают их с остальными моими тестами, что меня не волнует.

Так что я измеряю

Я измеряю только данные, прочитанные каждым методом - не считал данные или задержку базы данных, ни чтение диска, ни что-нибудь в этом роде. Позже на изображении с результатом я показываю, что на мерах нет дисковой активности
См. Это изображение, чтобы увидеть, что на самом деле я измеряю, и если это правильно

Почему я выбрал этот вид теста

Это просто, это реально, и это почти моя реальная проблема: я обнаружил задержку в Subson 3 в реальной программе с реальными данными.

Теперь давайте проверим далс

Начните с просмотра этого изображения У меня 4-5 вызовов на каждый метод, один за другим.

Результаты. Для цикла 100 раз попросите 5 строк, одна из которых не существует, приблизительно ..

Простой адонет: 81мс
SubSonic 2: 210 мс
linq2sql: 1,70 сек
linq2sql с использованием CompiledQuery.Compile: 239ms
Дозвуковой 3: 15,00 с (вау - очень медленно)

Проект http://www.planethost.gr/DalSpeedTests.rar


Может ли кто-нибудь подтвердить этот тест или внести какие-либо изменения, чтобы помочь мне?

Другие тесты

Кто-то публикует здесь эту ссылку http://ormbattle.net/ (а затем удаляет ее - не знаю почему). На этой странице вы можете найти действительно полезные расширенные тесты для всех, кроме дозвуковых 2 и дозвуковых 3, которые у меня есть здесь !

Оптимизация

Что я действительно спрашиваю, так это то, может ли кто-нибудь теперь уловить, как оптимизировать DAL, не изменяя тестовый код, а изменяя код и настройки каждого dal. Например ...

Оптимизация Linq2SQL

Я начал поиск, как оптимизировать Linq2sql и нашел эта статья , а может и больше существует.

Наконец, я запускаю трюки с этой страницы и оптимизирую код, используя их все. Скорость была около 1,50 с от 1,70 .... большое улучшение, но все еще медленно.

Тогда я нашел другой путь - та же самая статья идеи , и вау! скорость взорвалась. Используя этот трюк с CompiledQuery.Compile, время от 1,5 с теперь составляет 239 мс. Вот код для предварительно скомпилированного ...

Func<DataClassesDataContext, int, IQueryable<Product>> compiledQuery =
    CompiledQuery.Compile((DataClassesDataContext meta, int IdToFind) =>
                          (from myData in meta.Products
                           where myData.ProductID.Equals(IdToFind)
                           select myData));

StringBuilder Test = new StringBuilder();
int[] MiaSeira = { 5, 6, 10, 100, 7 };

using (DataClassesDataContext context = new DataClassesDataContext())
{
    context.ObjectTrackingEnabled = false;

    for (int i = 0; i < 100; i++)
    {
        foreach (int EnaID in MiaSeira)
        {
            var oFindThat2P = compiledQuery(context, EnaID);

            foreach (Product One in oFindThat2P)
            {
                Test.Append("<br />");
                Test.Append(One.ProductName);
            }
        }
    }
}

Оптимизация SubSonic 3 и проблемы

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

Вот некоторые снимки моих точек профилирования и задержки внутри дозвукового исходного кода

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

Попробуйте сделать прекомпиляцию до дозвуковой 3, как я делал в linq2Sql, но пока что не получится ...

Оптимизация SubSonic 2

После того, как я обнаружил, что дозвуковая 3 чрезвычайно медленная, я начинаю свои проверки на дозвуковой 2 - чего я никогда не делал, прежде чем поверить, что это быстро. (и это так)

Так что придумали некоторые моменты, которые могут быть быстрее. Например, есть много подобных циклов , которые на самом деле медленны из-за манипулирования строками и сравниваются внутри цикла. Сразу скажу, что этот код вызывали миллион раз! в течение нескольких минут! запроса данных из программы.

Для небольшого количества таблиц и небольших полей, может быть, для некоторых это не большая мысль,

но на большом количестве таблиц задержка еще больше. Поэтому я сам решаю и оптимизирую дозвуковую 2, заменяя сравнение строк на сравнение чисел! Просто. Я делаю это почти во всех случаях, когда профилировщик говорит, что это медленно. Я также изменяю все маленькие точки, которые могут быть даже немного быстрее, и отключаю некоторые не очень используемые мысли.

Результаты, на 5% быстрее в базе данных NorthWind, почти на 20% быстрее в моей базе данных с 250 таблицами. Это означает, что при скорости северного ветра за 10 секунд процесс сокращается на 500 мс, в моей базе данных - на 100 мс быстрее, чем на 500 мс. У меня нет снимков, чтобы показать вам это, потому что я сделал их с другим кодом, с другим временем и выследил их на бумаге.

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

Для этих мер я использую оптимизированную мной Subsonic 2.2, немного оптимизированную Subsonic 3.0.0.3 и Dot.Net 3.5

Ответы [ 5 ]

3 голосов
/ 07 марта 2010

Аристос, вот с чем у меня проблема. Вы отправили вопрос нашим группам, и у нас был хороший 23-летний обмен электронной почтой. Вы настояли , что у SubSonic 3 есть проблемы, и спросили меня, почему я не исправил этот "медленный, сломанный инструмент".

Я пытался объяснить вам, что при 233 таблицах SubSonic должен читать схему EACH ONE при загрузке. Это не типичное использование для SubSonic 3, но мы делаем это таким образом, так что это на самом деле быстрее, чем SubSonic 2 при последующих загрузках.

Ты любишь это. Я отвечаю тебе. RBarry оставил комментарий выше, что я был "клеветой". Я очень расстроен. Вы, кажется, думаете, что я не тестировал эту вещь, и я, МНОГИЕ раз. Я не могу получить ORM с проблемами, подобными той, которую вы предложили, а я нет.

Вы должны понимать, что если SubSonic потребовалось 10 секунд для выполнения запроса, он не будет использоваться.

Итак - ваш ответ: 233 таблицы, созданные в виде классов, необходимо загрузить в память провайдера при первом запуске.

Это слишком много. SubSonic не ваш инструмент.

1 голос
/ 02 марта 2010

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

Если вы хотите действительно что-то сравнить, вам нужно использовать консоль и запускать циклы чтения, которые работают с индексированными данными. Что вы сделали, это создали веб-страницу и сказали: «Давайте посмотрим, что происходит при загрузке».

Это ошибочно по ряду причин. Во-первых, весь написанный код должен быть скомпилирован из IL do ML. Поскольку SubSonic генерирует ваш код для вас, и, поскольку я знаю, что у вас здесь много таблиц (более 300, если я правильно помню), вы можете себе представить, что при первой загрузке происходит некоторая работа.

Чтобы быть совершенно честным здесь - ваша неопытность уничтожает большую часть работы, которую я положил бесплатно, публикуя такие вещи, как "это медленно и не готово". Меня не волнует, используют ли люди SubSonic - мне все равно, когда люди делают глупости (например, тесты веб-тестов) и обвиняют меня в этом.

1 голос
/ 04 марта 2010

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

 StringBuilder Test = new StringBuilder();
 int[] MiaSeira = { 5, 6, 10, 100, 7 };
 for (int i = 0; i < 100; i++)
 {
     foreach (int EnaID in MiaSeira)
     {
         var Products = (from product in Product.
             where MiaSeira.Contains(product.ProductID)
             select product).ToList();

         if (Products == null || Products.Count == 0)
             continue;

         foreach (Product product in Products)
         {
            Test.Append("<br />");
            Test.Append(product.ProductName);
         }
     }
 }

 txtDebug.Text = Test.ToString();
1 голос
/ 02 марта 2010

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

0 голосов
/ 04 марта 2010

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

...