Dapper.NET — «микро-ORM» на котором работает StackOverflow

    Dapper.NET — это «мини-ORM», как ее называют сами разработчики, на которой работает движок StackExchange и сайт StackOverflow в частности.

    Сегодня Sam Saffron (@samsaffron, один из разработчиков платформы) выложил ее в OpenSource на Google Code.

    Основная фишка этой микро-библиотеки — производительность в тех случаях, когда надо запустить, например, 500 select-команд подряд и замапить тысячи результатов в объекты определенных классов. Разработчики утверждают, что скорость их решения практически не уступает «ручной» работе с SqlDataReader.

    Сам Сэм описал эту микро-либу в своем блоге вот тут, признав, в частности, что его решение прежде всего «read-oriented» — т.е. в первую очередь рассчитано на быстрое чтение. Там же, в статье, Сэм описывает причины, почему они решили отказаться от Linq2SQL там, где важна производительность. А именно — из-за низкой скорости.

    PS. Простите, добавлю свое личное ХО: сайт StackOverflow — это чуть-ли не самый большой и посещаемый сайт в мире, построенный на .NET-платформe (а не на Руби/Рельсах, PHP и пр). Нагрузка — ого-го. Именно поэтому нам, NET-программерам, стоит пристально следить за всеми фишками, которые ребята пробуют.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 50

      +1
      Жаль, что автор не включил в обзор производительности сравнение с BLToolkit =)

      По самой библиотеке — забавно, она в виде одного файла, можно включать куда угодно. Используется эмитинг. Мега-ORM она не заменит (да и использовать ее можно только с MS SQL Server), но для простых приложений — вполне можно. Также интересно поглядеть, как автор добивается высокой скорости маппинга.
        +1
        Вставлю свои 5 копеек. Маппинг BLToolkita тормозной в сравнении с тем же emitmapper. Все хорошо при объемах в тысячи объектов но десятки и сотни тысяч начинались тормоза. В свое время отказались от него по этой причине. Плюс иногда выдавал совершенно дурные SQL запросы обрабатывая linq выражения. Может сейчас чтото и подделали, опыт был в 2009 — 2010 годах.
          0
          Оговорюсь — я имел ввиду маппинг просто объектов между собой а не с базы. в итоге остановились на .netTiers + emitmapper
          0
          Автор BLToolkit'а где-то год назад переписал маппинг и на форуме RDSN ехидненько написал что-то вроде «Emit Mapper может идти тренироваться дальше».

          Emit Mapper, кстати, в развитии остановился почему-то, больше года уже нет обновлений, хотя когда я эту библиотеку пробовал, уже была вполне законченным рабочим продуктом.
            0
            Парень подготовил код под статью на хабре, а после этого забил на код. А на самом то деле он, по крайней мере на тот момент, был быстрее AutoMapper который щас очень популярен.
              0
              Да, в этом плане AutoMapper, все-таки, более удобен в использовании, клевое API и набор фич, и все такое, хотя EmitMapper, конечно, был намного быстрее, по крайней мере, когда я тестировал их в сравнении.
              +1
              Хм, обратите внимание на эту статью habrahabr.ru/blogs/net/80793/.

              EmitMapper сравним по скорости с ручным кодом, так что автор блтулкита либо научился выполнять MSIL код быстрее фрейморка либо заливает :).

              Пользуюсь им везде где необходимо делать клонирование объектов. Раньше по незнанию пользовался XmlSerializer но это огромный провал по производительности.
                0
                Статья от января 2010 года.
                Вот сообщение автора BLToolkit'а rsdn.ru/forum/prj.rfd/3723299.1.aspx, от марта 2010 г.

                «Производительность, конечно, процентов на несколько хуже, чем рукописный код, но всякие ЕмитМаперы могут идти тренироваться дальше.»

                  0
                  Ну, EmitMapper, если и медленнее, чем BLT, то в таких ничтожных масштабах, что можно пренебречь.
                    0
                    хм… надо будет посмотреть :) даже прям попробовать!
                      0
                      Это сообщение из серии «сам себя не похвалишь, никто не похвалит», никаких тестов и подтверждающих фактов. Так что я бы не стал доверять таким категоричным высказываниям.
                        0
                        Писал не тот человек, который склонен заниматься пустой похвальбой. Цифр там действительно нет, но я уверен, что если провести испытания — его слова подтвердятся.
                          0
                          Это ваше субъективное мнение, а объективная картина может быть другой. Мне вот интересно, как вы можете быть уверены в цифрах, когда никаких испытаний не проводили? Вся ваша уверенность в технологии основана на косвенных знаниях о чертах характера отдельного человека.

                          Человек выше правильно сказал:
                          EmitMapper сравним по скорости с ручным кодом, так что автор блтулкита либо научился выполнять MSIL код быстрее фрейморка либо заливает

                          Тут нужны цифры и испытания, а не голословные утверждения, что вы уверены.
                            0
                            Как бы вам попроще объяснить…

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

                            Так вот, я знаю, что:
                            1. Сообщение, на которое я дал ссылку, написал автор и практически единственный коммитер проекта BLToolkit, и репутация у него на форуме RSDN очень высокая. Мы не совершим особо уж большой вольности, если допустим, что это человек, который знает возможности своего продукта и отвечает за свои слова.
                            2. Автор BLToolkit принимал непосредственное участие в тестах и обсуждении EmitMapper'а.

                            Теперь внимательно читаем фразу «Производительность, конечно, процентов на несколько хуже, чем рукописный код, но всякие ЕмитМаперы могут идти тренироваться дальше.» =) Разделим ее на две части.

                            «Производительность, конечно, процентов на несколько хуже, чем рукописный код» — тут, надеюсь, никаких противоречий и всяких когнитивных диссонансов? =) У эмитмаппера производительность на несколько процентов хуже, и у блтулкита несколько хуже. Ну, бывает =)

                            «но всякие ЕмитМаперы могут идти тренироваться дальше» — ну, я тоже уверен, что они могут идти тренироваться дальше. Всегда есть к чему стремиться =) Например, к тому, чтобы производительность была равна производительности рукописного кода.

                            Да, мое мнение субъективно =) как и всякое другое. И моя уверенность в технологии основана на личном применении. Это тоже субъективно, конечно =)

                            И если вам нужны цифры, просто проведите испытания, а не цепляйтесь от делать нефиг =)
                              0
                              Правду говорят. только что проверил. по крайней мере на простом тесте раза в полтора шустрей.
                            0
                            В данный момент пишу тест, уж больно заинтересовала свежая версия блтулкита. Как будут данные напишу сюды :)
                              +1
                              Вобщем, ребята исправились, маппинг работает оч хорошо.
                              результат простого теста без глубокого мэппинга

                              Test for 1 items
                              BLToolkit time:00:00:00.0000013
                              EmitMapper time:00:00:00.0000018
                              Test for 10 items
                              BLToolkit time:00:00:00.0000022
                              EmitMapper time:00:00:00.0000031
                              Test for 100 items
                              BLToolkit time:00:00:00.0000144
                              EmitMapper time:00:00:00.0000208
                              Test for 1000 items
                              BLToolkit time:00:00:00.0001335
                              EmitMapper time:00:00:00.0001883
                              Test for 10000 items
                              BLToolkit time:00:00:00.0013372
                              EmitMapper time:00:00:00.0022130
                              Test for 100000 items
                              BLToolkit time:00:00:00.0135715
                              EmitMapper time:00:00:00.0192261
                              Test for 1000000 items
                              BLToolkit time:00:00:00.1399616
                              EmitMapper time:00:00:00.1949009
                              Test for 10000000 items
                              BLToolkit time:00:00:01.3721950
                              EmitMapper time:00:00:01.9405558
                              Test for 100000000 items
                              BLToolkit time:00:00:13.5768732
                              EmitMapper time:00:00:19.3475230

                              гдето раза в полтора скорость выше.
                                0
                                Спасибо, интересные результаты. На чем тестировали?
                                  0
                                  просто два класса с одинаковыми полями (типы ссылочные и по значению) ну и мапировал из одного в другой. скорость несравненно стала лучше. просто год назад я как раз на этом попался и перескочил на эмитмаппер.
                                  сейчас поглядел как генерится sql из linq выражений — очень недурно, захотелось обратно на блтулкит переходить. уж больно код выходит простой, вобщем надо погонять на хитрых запросах и делать выводы.
                        0
                        Там в комментариях была такая ссылка, как раз от автора BLT, могу повторить здесь.
                        rsdn.ru/forum/dotnet/3658986.1.aspx
                        Дальше обсуждение тоже интересное.

                        После этой дискуссии маппер в BLT вроде бы подкрутили.
                        rsdn.ru/forum/prj.rfd/3669725.1.aspx

                          0
                          И вправду подкрутили, мой тест в комментах выше — гдето раза в полтора шустрее на протых объектах
                      0
                      На тестах маппинга из БД, BLToolkit самый быстрый из всех широкодоступных мапперов. По крайней мере из тех, которые тестировались на ORMBattle.
                      ormeter.net/
                      Поскольку там тоже эмитт, как и в описываемой тулзе, подозреваю, что и результаты сравнимые. Другое дело, что инструмент из статьи заточен под конкретную задачу, а BLT довольно универсальный инструмент при всей своей относительной простоте…
                      Вообще BLT — это то, как должен был выглядеть Linq2SQL, если бы его не бросили. )

                        +1
                        Тесты, кстати, там довольно давно не обновлялись. За прошедшее время DataObjects допилили свой LINQ-провайдер, зарелизился NHibernate 3 с переделанным LINQ. Интересно было бы посмотреть актуальные результаты.
                    +1
                    StackOverflow был самым большим примеро использования Linq2SQL. Эх…
                      0
                      По ссылке написано:
                      This allows us to continue using LINQ-2-SQL where performance does not matter and port all our inline SQL to use our mapper, since it is faster and more flexible.
                      (курсив мой). То есть, видимо, он таковым и остается.
                        0
                        Да, ссылка появилась позже моего коментария. Я и хотел написать опровержение своим словам, но несложилось.
                          0
                          Насколько я понял, в их новом ORM запросы пишутся на SQL, так что основной движок больше не на Linq2SQL. А Linq2SQL оставлен для мест, где не требуется высокая производительность.
                        –2
                        Просто шикарно.
                          0
                          Добавил в статью ссылку на блог Сэма
                            0
                            сайт StackOverflow — это чуть-ли не самый большой и посещаемый сайт в мире, построенный на .NET-платформe


                            Если .Net заменить на Asp.net MVC то пожалуй, а так еще есть как минимум:
                            www.myspace.com/ и www.plentyoffish.com/ которые более нагруженные.
                              0
                              myspace переписали на aspnet mvc? вот это да!
                                0
                                прочитайте еще раз, я имел ввиду полностью обратное
                                0
                                Да, но ни myspace, ни plentyoffish не испытывают такой нагрузки *ОТ GOOGLE*, как stackoverflow. Сэм же пишет в блоге (см ссылку), что индексация страниц иногда доходит до 10 раз в секунду. Не думаю, что гугл настолько «любит» myspaсe :)
                                +1
                                Ключевая фишка не в том, что это ORM (по feature-set ей до того же NHibernate еще очень далеко — но тут сравнение неуместно, у них разные задачи). Я бы даже сказал, что это не ORM, а скорее некоторый простой Query+Mapper. Неудивительно, что он так быстр в своих задачах. ORM для таких сценариев не предназначены. Сила ORM — в OLTP-сценариях. А вот Batch-select'ы — зачастую слабое место ORM, и Dapper закрывает именно этот сценарий.

                                Что они сделали — это отделили мух от котлет. А именно — разделили часть, ответственную за запросы (в особенности batch-запросы), т. е. SELECT и часть, ответственную за манипуляцию данными (т. е. INSERT, UPDATE, DELETE).
                                  +1
                                  Сила ORM не в OLTP сценариях, а в том, что они (якобы) позволяют не думать об SQL, а оперировать объектами. В этом же и их слабость, так как за все приходится платить — в данном случае как скоростью, так и различного рода побочными эффектами.
                                    0
                                    «Сила ORM не в OLTP сценариях, а в том, что они (якобы) позволяют не думать об SQL, а оперировать объектами.»

                                    Нет, в этом их _суть_ (в объектах). А использование оправдано именно для OLTP. Для массовой обработки данных, ETL и OLAP — ORM не подходят.

                                    И думать об SQL нужно в любом случае, ибо если вы серьезно работали с ORM на .NET, то должны знать, что мало замаппить схему БД в Domain-модель, нужно еще определить Fetch-стратегии, стратегии кэширования и стратегии управления сессиями и транзакциями.

                                    Скорость же и побочные эффекты — это уже вопрос реализации конкретных ORM.
                                  +3
                                  Печальный момент в том, что теперь множество людей бросится это использовать, потому что «быстрее», хотя реально это важно для приложений размера SO. А в остальных случаях гораздо счастливее испоьзовать полноценный ORM.
                                    0
                                    В чем печаль? Если подходит по условиям задачи (например, только селекты) — можно использовать. Не подходит — не будут использовать. Это же не выбор между «модными» фреймворками.
                                    А скорость много где важна. Попадаются клиенты, которые очень не любят, когда простые выборки данных (любых) делаются, на их взгляд, медленно,
                                      0
                                      Печаль в том случае, когда подходит по условиям сегодняшней задачи, а потом это расширять.

                                      Что касается клиентов, то в хорошем приложении UI тормозить не должен в любом случае (для этого есть кеш и не только), а лезущих в код надо хотя бы пытаться перепрограммировать.
                                        0
                                        Согласен с вами. Ну, видимо, SO — достаточно высоконагруженный сайт, что им помимо кэша потребовалось поменять и сам механизм Read-части доступа к данным. Кстати, еще интересно, они упоминают, что не кэшируют контент для авторизованных пользователей, ибо у них 90% трафика — «неавторизованный» трафик с Гугла. Может оставшиеся 10% решили оптимизировать и таким вот способом тоже.
                                    +2
                                    сайт StackOverflow — это чуть-ли не самый большой и посещаемый сайт в мире, построенный на .NET-платформe

                                    Все-таки самый большой .Net сайт по посещаемости будет пожалуй msn.com — если я правильно помню, 9.5K запросов в секунду, что входит в пятерку самых нагруженных сервисов и больше чем на порядок превышает нагрузку SO. Там asp.net, mvc, вроде бы уже razor. Ну и куча своих фишек по оптимизации, конечно же, но все естественно win+net.
                                    • UFO just landed and posted this here
                                      • UFO just landed and posted this here
                                          0
                                          У вас, похоже, не вызывается Enumerator для запросов LINQ-2-SQL и EF. Ведь данные нигде не используются, и он не вызывается неявно (соответственно, ничего не выбирается из базы — ибо нет команды на deferred execution).

                                          Добавьте ".ToList()" к запросам (обратите внимание, что в оригинальных тестах использовался extension-метод ".First()", который сам по себе возвращает один экземпляр; если бы они написали ".Take(1)", то также нужно было бы добавлять ".ToList()").

                                          А такая непропорциональная разница во времени пусть вас не смущает — движок БД сам производит самые разные оптимизации на разные запросы, плюс сами ORM по-разному оптимизируют и формируют их.

                                          P.S. Самое забавное, то первый (исходный) тест отражает реальный сценарий использования, а простая выборка 100 записей — не дает никакого представления о том, как система будет вести себя в реальности.
                                          0
                                          В трекере уже попросили добавить также сравнение с bltoolkit. Стало очень интересно, сел прикручивать bltoolkit.
                                            0
                                            Протестировал с bltoolkit, на моей машине результаты оказались следующие:

                                            Running 500 iterations that load up a post entity
                                            — hand coded took 109ms
                                            — Mapper Query took 118ms
                                            — PetaPoco (Normal) took 130ms
                                            — Dynamic Massive ORM Query took 132ms
                                            — Dynamic Mapper Query took 136ms
                                            — PetaPoco (Fast) took 136ms
                                            BLToolkit took 184ms
                                            — Linq 2 SQL Compiled took 206ms
                                            — SubSonic Coding Horror took 277ms
                                            — NHibernate SQL took 325ms
                                            — NHibernate HQL took 388ms
                                            — Linq 2 SQL ExecuteQuery took 451ms
                                            — Entity framework ExecuteStoreQuery took 1287ms
                                            — Linq 2 SQL took 1347ms
                                            — Entity framework took 2098ms
                                            — SubSonic ActiveRecord.SingleOrDefault took 7980ms
                                              0
                                              А EF использовали последней версии? Просто что-то уж совсем зверский разрыв. Неужели так всё плохо для флагманской ORM от MS?
                                              0
                                              Поправьте меня если я не прав, но насколько я понял, Dapper это просто query-mapper (как тут уже верно отметили) и он не позволяет работать через LINQ запросы к объектам (т.е. LINQ to SQL маппера нет).

                                              А есть ли информация о сравнении операций выборки данных с LINQ to SQL mapping + result object mapping для разных библиотек?

                                              Only users with full accounts can post comments. Log in, please.