Re[7]: [ANN] Emit Mapper
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 30.12.09 23:09
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Задумывался. Именно по-этому в тесте есть строчка (выделено жирным):


Что то у тебя явно не то.
... << RSDN@Home 1.2.0 alpha 4 rev. 1324 on Windows 7 6.1.7600.0>>
AVK Blog
Re[8]: [ANN] Emit Mapper
От: WolfHound  
Дата: 31.12.09 09:30
Оценка:
Здравствуйте, AndrewVK, Вы писали:

T>>Задумывался. Именно по-этому в тесте есть строчка (выделено жирным):

Так очевидно что именно...

d = BLToolkit.Mapping.Map.ObjectToObject<A2>(s);

mapper.Map(s, d);

BLT каждый раз создает новый объект. EM тупо копирует в один и тотже не напрягая GC.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: [ANN] Emit Mapper
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.12.09 09:33
Оценка:
Здравствуйте, WolfHound, Вы писали:

T>>>Задумывался. Именно по-этому в тесте есть строчка (выделено жирным):

WH>Так очевидно что именно...

WH>d = BLToolkit.Mapping.Map.ObjectToObject<A2>(s);


WH>mapper.Map(s, d);


WH>BLT каждый раз создает новый объект. EM тупо копирует в один и тотже не напрягая GC.


Ясно. Что то подобное я и предполагал.
... << RSDN@Home 1.2.0 alpha 4 rev. 1324 on Windows 7 6.1.7600.0>>
AVK Blog
Re[9]: [ANN] Emit Mapper
От: mrTwister Россия  
Дата: 31.12.09 12:03
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Так очевидно что именно...


WH>d = BLToolkit.Mapping.Map.ObjectToObject<A2>(s);


WH>mapper.Map(s, d);


WH>BLT каждый раз создает новый объект. EM тупо копирует в один и тотже не напрягая GC.


Дак это проблемы BLT. Он другого интерфейса не предоставляет.
Плюс к этому BLT при конвертации value типов делает боксинг/анбоксинг. EM обходится без этого.
лэт ми спик фром май харт
Re[10]: [ANN] Emit Mapper
От: WolfHound  
Дата: 31.12.09 15:12
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Дак это проблемы BLT. Он другого интерфейса не предоставляет.

T>Плюс к этому BLT при конвертации value типов делает боксинг/анбоксинг. EM обходится без этого.
Лично я вижу только одно объяснение этому: Данные сценарии за все время существования BLT ни кому ни разу не понадобились.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: [ANN] Emit Mapper
От: IT Россия linq2db.com
Дата: 03.01.10 05:07
Оценка: 59 (5)
Здравствуйте, mrTwister, Вы писали:

T>http://emitmapper.codeplex.com


Совсем не плохо.

Там где можно дженерик методы можно было бы переписать следующим образом:

static class MapperImpl<TFrom,TTo>
{
    public static ObjectsMapper<TFrom,TTo> Instance = new ObjectsMapper<TFrom, TTo>(
        new ObjectsMapperManager().GetMapperImpl(
            typeof(TFrom),
            typeof(TTo),
            DefaultMapConfig.Instance
        )
    );
}

public ObjectsMapper<TFrom, TTo> GetMapper<TFrom, TTo>()
{
    return MapperImpl<TFrom,TTo>.Instance;
}

Тогда время на инициализацию и получение мапперов можно свести практически в абсолютный ноль.

Сравнительный тест с BLT конечно же слегка наивен. В тесте BLT тестируется не столько маппинг, сколько время доступа к мапперу. Впрочем, обо всём по порядку.

T>Имхо, заставлять вешать атрибуты — это еще больший моветон. Это примерно как заставлять наследоваться от специального класса. Тем более, что ничто не мешает реализовать требуемую функциональность своими силами на основе Emit Mapper.


Этот подход ведёт в никуда. Пользователям нужна готовая функциональность, а не потенциальная возможность. Это я как собаковод говорю. "ничто не мешает реализовать" в 99.99% случаев означает, что никто ничего реализовывать никогда и не будет. Более того, разработчик инструмента должен держать своё мнение о моветонах при себе. Учить пользователей жизни — это не его работа. Нормальное объяснение отсутсвия какой-либо функциональности в инструменте это: лень, нет времени, технические проблемы, отсутствие выгоды и т.п. "еще больший моветон" можно обсуждать у нас в Философии и желательно вне контекста конкретного инструмента.

T>Как раз как маппер, БЛТ довольно слабый (ценность БЛТ не в маппере). Он не поддерживает даже вложенные объекты, не конфигурируется и т.д. По крайней мере не справился даже с такой простой задачкой:


Как раз как маппер, в реальных сценариях BLT даст фору кому угодно. "Даже вложенные объекты" в BLT не поддерживаются по-умолчанию. Кстати, они не поддерживаются по-умолчанию практически нигде, т.к. это вызывает больше проблем, чем бенефитов. Научить BLT справляться с поставленной задачкой можно, например, следующим образом:

[MapField("str2", "i.str2")]
public class Destination
{
    public class Int
    {
        public string str2;
    }

    public string str1;
    public Int i = new Int();
}

[MapField("str2", "i.str2")]
public class Source
{
    public class Int
    {
        public string str2 = "B1::Int::str2";
    }

    public string str1 = "B1::str1";
    public Int i = new Int();
}

T>Да и производительность у БЛТ маппера оставляет желать лучшего. На простеньком тесте (класс без вложеных объектов) БЛТ оказался в 250 раз медленнее. Вот код теста:

Думаю, любому взрослому и умному человеку, заинтересованному в конечном результате, обязательно захотелось бы найти объснению такому чудовищному отставанию в производительности и разобраться что же происходит на самом деле, а не отмазываться фразами вроде "Дак это проблемы BLT. Он другого интерфейса не предоставляет.". Тем более, что и интерфейс такой у BLT есть и у EM есть интерфейс, который поставил бы библиотеки в одинаковые условия. И тогда 250 раз мгновенно уменьшились бы на 125. Хотя проблема, конечно, не в этом.

Разница в производительности объясняется прежде всего тем, что в тесте EM тестируется только маппер, а в тесте BLT тестируется не столько маппер, сколько способ его получения. API для получения маппера как это происходит в сценарии в BLT попросту отсутствует. Не то что бы это было трудно сделать, но просто за 8 лет существования библиотеки это пока никому не было нужно. Сценариев где нужен маппинг одного объектв в другой не так много, высокопроизводительных сценариев ещё меньше, а когда они реально возникают, то написать код вручную, особенно сегодня при наличии инициализаторов в C# не представляет особой сложности.

В общем, BLT под такие сценарии никогда не оптимизировался. Другое дело вот такие сценарии:

public class A2
{
    public string str1;
    public string str2;
    public string str3;
    public string str4;
    public string str5;
    public string str6;
    public string str7;
    public string str8;
    public string str9;

    public int n1;
    public int n2;
    public int n3;
    public int n4;
    public int n5;
    public int n6;
    public int n7;
}

public class B2
{
    public string str1 = "str1";
    public string str2 = "str2";
    public string str3 = "str3";
    public string str4 = "str4";
    public string str5 = "str5";
    public string str6 = "str6";
    public string str7 = "str7";
    public string str8 = "str8";
    public string str9 = "str9";

    public int n1 = 1;
    public long n2 = 2;
    public short n3 = 3;
    public byte n4 = 4;
    public decimal n5 = 5;
    public float n6 = 6;
    public int n7 = 7;

}

static long BenchBLToolkit_List(int mappingsCount)
{
    var list = new List<B2>();

    for (var i = 0; i < mappingsCount; i++)
        list.Add(new B2());

    var sw = new Stopwatch();
    sw.Start();

    var dest = Map.ListToList<A2>(list);

    sw.Stop();
    return sw.ElapsedMilliseconds;
}

static long EmitMapper_List(int mappingsCount)
{
    var list = new List<B2>();

    for (var i = 0; i < mappingsCount; i++)
        list.Add(new B2());

    var sw = new Stopwatch();
    sw.Start();

    var mapper = ObjectsMapperManager.DefaultInstance.GetMapper<B2, A2>();
    var dest   = new List<A2>();

    foreach (var item in list)
        dest.Add(mapper.Map(item));

    sw.Stop();
    return sw.ElapsedMilliseconds;
}

Здесь мы уже имеем разницу не в 250 раз, а около двух, хотя и не в пользу BLT. Оставшаяся разница объясняется тем, что BLT делает больше проверок в рантайм. Например, если изменить приведённый выше код следующим образом, то EM упадёт:

public class B2
{
    ...
    public decimal? n5 = null;
    ....
}

Некоторые из этих проверок можно сократить только генерацией кода под каждый конкретный вариант использования, что практически не имеет смысла если не кешировать каким-то образом сам вариант использования или явно не напрягать пользователя, что бы он его как-то идентифицировал. В приведённых выше тестах EM именно этим и занимается. Это хорошо работает с объектами, но не работает с источниками данных, структура которых становится известной только в момент выполнения. К таким источникам относятся, например, базы данных. Кстати, давайте посмотрим что у нас с базами данных:

static long BLToolkit_DB(int mappingsCount)
{
    DbManager.AddConnectionString("data source=.;initial catalog=Northwind;integrated security=SSPI;");

    var sw = new Stopwatch();
    sw.Start();

    for (var i = 0; i < mappingsCount; i++)
    {
        using (var db = new DbManager())
        {
            var list = db
                .SetCommand("SELECT * FROM Customers")
                .ExecuteList<Customers>();
        }
    }

    sw.Stop();
    return sw.ElapsedMilliseconds;
}

static long EmitMapper_DB(int mappingsCount)
{
    var sw = new Stopwatch();
    sw.Start();

    for (var i = 0; i < mappingsCount; i++)
    {
        using(var con = new SqlConnection("data source=.;initial catalog=Northwind;integrated security=SSPI;"))
        using(var cmd = con.CreateCommand())
        {
            con.Open();

            cmd.Connection  = con;
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandText = "SELECT * FROM Customers";

            using (var reader = cmd.ExecuteReader())
            {
                var list  = reader.ToObjects<Customers>(null).ToList();
            }
        }
    }

    sw.Stop();
    return sw.ElapsedMilliseconds;
}

В этом примере EM уже начинает отставать. Скорее всего reader.ToObjects, взятый из примеров библиотеки не очень хорош. При этом он не очень хорош будучи написанным самим автором библиотеки, а что будет написано, если будет, пользователями, плохо знакомыми как с самой библиотекой, так и с базами данных?

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

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

public DTOCustomer GetCustomer(Guid customerId)
{
    using (var dc = new DataContext())
    {
        var customer = dc.Customers.Where(c => c.CustomerID == customerId).Single();
        return ObjectsMapperManager.DefaultInstance.GetMapper<Customer, DTOCustomer>().Map(customer);
    }
}

И в самом самом заключении, ObjectsMapperManager — это немного не по-английски.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: [ANN] Emit Mapper
От: Holms США  
Дата: 03.01.10 05:51
Оценка: 58 (1)
Здравствуйте, IT, Вы писали:

пост не в тему, но
последняя версия BL из svn не компилится, можете поправить
вот пара ошибок

 EditableObjects\NotifyCollectionChangeTest.cs(497,48): error CS0433: The type 'System.Collections.Specialized.NotifyCollectionChangedEventArgs' exists in both 'f:\svn\bl-toolkit\Source\bin\Release\BLToolkit.3.dll' and 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll'
EditableObjects\NotifyCollectionChangeTest.cs(62,58): error CS0433: The type 'System.Collections.Specialized.NotifyCollectionChangedEventArgs' exists in both 'f:\svn\bl-toolkit\Source\bin\Release\BLToolkit.3.dll' and 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll'
EditableObjects\NotifyCollectionChangeTest.cs(446,52): error CS0433: The type 'System.Collections.Specialized.NotifyCollectionChangedEventArgs' exists in both 'f:\svn\bl-toolkit\Source\bin\Release\BLToolkit.3.dll' and 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll'
Done Building Project "F:\svn\bl-toolkit\UnitTests\CS\UnitTests.CS.csproj" (default targets) -- FAILED.
Project "F:\svn\bl-toolkit\BLToolkit.2008.sln" (1) is building "F:\svn\bl-toolkit\UnitTests\Linq\UnitTests.Linq.csproj" (13) on node 0 (default targets).
  Processing 0 EDMX files.
  Finished processing 0 EDMX files.
ConvertTest.cs(7,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
CompileTest.cs(7,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
MathFunctions.cs(3,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
Exceptions\Inheritance.cs(6,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
Model\NorthwindDB.cs(4,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
Exceptions\Mapping.cs(5,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
Functions.cs(7,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
DateTimeFunctions.cs(6,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
StringFunctions.cs(8,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
TestDbManager.cs(4,22): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
WhereTest.cs(11,23): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'BLToolkit.Data' (are you missing an assembly reference?)
Model\NorthwindDB.cs(14,10): error CS0246: The type or namespace name 'Table' could not be found (are you missing a using directive or an assembly reference?)
Model\NorthwindDB.cs(15,10): error CS0246: The type or namespace name 'Table' could not be found (are you missing a using directive or an assembly reference?)
Model\NorthwindDB.cs(16,10): error CS0246: The type or namespace name 'Table' could not be found (are you missing a using directive or an assembly reference?)



Кстати, какие планы насчет Silverlight-а. Будет поддержка?
Спасибо
... << RSDN@Home 1.2.0 alpha 4 rev. 1253>>
The life is relative and reversible.
Re[3]: [ANN] Emit Mapper
От: IT Россия linq2db.com
Дата: 03.01.10 06:35
Оценка:
Здравствуйте, Holms, Вы писали:

H>пост не в тему, но

H>последняя версия BL из svn не компилится, можете поправить
H>вот пара ошибок

Только что пересобрал в обоих фреймворках. Компилируется нормально. Может какие-то проблемы с локальной версией?

H>Кстати, какие планы насчет Silverlight-а. Будет поддержка?


Сделаем. Технических проблем пока вроде не видно.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: [ANN] Emit Mapper
От: Holms США  
Дата: 03.01.10 06:42
Оценка:
Здравствуйте, IT, Вы писали:

IT>Только что пересобрал в обоих фреймворках. Компилируется нормально. Может какие-то проблемы с локальной версией?

а какие проблемы могут быть? я взял то что в SVN-е потом запустил
%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.2008.sln  /property:Configuration=Release

может кое-что не попало в SVN?

IT>Сделаем. Технических проблем пока вроде не видно.

отлично. Any ETA?
... << RSDN@Home 1.2.0 alpha 4 rev. 1253>>
The life is relative and reversible.
Re[5]: [ANN] Emit Mapper
От: IT Россия linq2db.com
Дата: 03.01.10 06:57
Оценка:
Здравствуйте, Holms, Вы писали:

IT>>Только что пересобрал в обоих фреймворках. Компилируется нормально. Может какие-то проблемы с локальной версией?

H>а какие проблемы могут быть? я взял то что в SVN-е потом запустил
H>
H>%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.2008.sln  /property:Configuration=Release
H>

H>может кое-что не попало в SVN?

Current SVN snapshots отсюда собираются путём скачки последней версии в чистый каталог и запуском

%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.3.csproj /property:Configuration=Release

Твой вариант я тоже только что проверил, всё работает.

IT>>Сделаем. Технических проблем пока вроде не видно.

H>отлично. Any ETA?

Что нужнее, DML или SL?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: [ANN] Emit Mapper
От: Holms США  
Дата: 03.01.10 07:10
Оценка:
Здравствуйте, IT, Вы писали:

IT>Current SVN snapshots отсюда собираются путём скачки последней версии в чистый каталог и запуском


IT>
IT>%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.3.csproj /property:Configuration=Release
IT>

IT>Твой вариант я тоже только что проверил, всё работает.
я беру отсюда http://bl-toolkit.googlecode.com/svn/trunk
мне выдаёт Revision 864, и файла BLToolkit.3.csproj в руте нету.

что-то здесь не то, и вот что конкретно

если брать откуда я беру то получаем всё что там е тебя есть, и файл BLToolkit.2008.sln не содержит линк на Source/BLToolkit.3.csproj

после запуска Source/Compile3.bat то и BLToolkit.2008.sln собралось без проблем.

IT>Что нужнее, DML или SL?

что скрывается под DML?
... << RSDN@Home 1.2.0 alpha 4 rev. 1253>>
The life is relative and reversible.
Re[7]: [ANN] Emit Mapper
От: Jack128  
Дата: 03.01.10 08:03
Оценка: +2
Здравствуйте, Holms, Вы писали:

IT>>Что нужнее, DML или SL?

H>что скрывается под DML?

update/insert/delete запросы. И они нужнее -)
Re[3]: [ANN] Emit Mapper
От: IT Россия linq2db.com
Дата: 03.01.10 16:25
Оценка:
Здравствуйте, Holms, Вы писали:

H>пост не в тему, но

H>последняя версия BL из svn не компилится, можете поправить

Нашёл.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: [ANN] Emit Mapper
От: Holms США  
Дата: 04.01.10 10:04
Оценка:
Здравствуйте, IT, Вы писали:

IT>Нашёл.

отлично

теперь ждём DML для LINQ-a
большая просьба, не мудрите с этим, сделаете просто как в SubSonic, а не как в Linq2Sql от MS.

Спасибо

Silverlight пока можно пропустить.
... << RSDN@Home 1.2.0 alpha 4 rev. 1253>>
The life is relative and reversible.
Re[2]: [ANN] Emit Mapper
От: mrTwister Россия  
Дата: 04.01.10 10:31
Оценка: +1
Здравствуйте, IT, Вы писали:

IT>Совсем не плохо.

Спасибо!

IT>Там где можно дженерик методы можно было бы переписать следующим образом:

IT>
IT>static class MapperImpl<TFrom,TTo>
IT>{
IT>    public static ObjectsMapper<TFrom,TTo> Instance = new ObjectsMapper<TFrom, TTo>(
IT>        new ObjectsMapperManager().GetMapperImpl(
IT>            typeof(TFrom),
IT>            typeof(TTo),
IT>            DefaultMapConfig.Instance
IT>        )
IT>    );
IT>}
IT>public ObjectsMapper<TFrom, TTo> GetMapper<TFrom, TTo>()
IT>{
IT>    return MapperImpl<TFrom,TTo>.Instance;
IT>}
IT>

IT>Тогда время на инициализацию и получение мапперов можно свести практически в абсолютный ноль.


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

IT>Этот подход ведёт в никуда. Пользователям нужна готовая функциональность, а не потенциальная возможность. Это я как собаковод говорю. "ничто не мешает реализовать" в 99.99% случаев означает, что никто ничего реализовывать никогда и не будет. Более того, разработчик инструмента должен держать своё мнение о моветонах при себе. Учить пользователей жизни — это не его работа. Нормальное объяснение отсутсвия какой-либо функциональности в инструменте это: лень, нет времени, технические проблемы, отсутствие выгоды и т.п.


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

1) Стратегия "Рыба". Предугадать возможные варианты использования и реализовать под них готовую функциональность. (это как раз то, о чем ты говоришь)
2) Стратегия "Удочка". Предоставив пользователю интерфейс с помощью которого он может самостоятельно добиться желаемого результата. Тем самым автоматически покрывается большинство вариантов использования и даже те из них, о существовании которых автор библиотеки даже не подозревает.

Каждая из стратегий имеет свои достоинства и недостатки, соответственно исходить надо из задачи. Задача Object2Object mapping — это задача с очень смутными и неопределенными вариантами использования из-за того, что их очень много. Ведь сопоставление полей объектов можно выполнять кучей разных способов: можно основываться на именах и при этом либо учитывать регистр, или нет, учитывать префиксы типа "m_", "_" или нет, можно основываться на атрибутах (но этот метод не всегда применим и весьма негибок), можно основываться на специальных XML схемах — на чем угодно, на что может хватить фантазии разработчика (я уже не говорю о более сложных задачах типа преобразования типов, коллекций, дженериков, пост/пре обработки и т.д.). Трезво оценивая свои возможности я понял, что не смогу в приемлимые сроки спроектировать и реализовать интерфейс таким образом, чтобы он покрыл все эти варианты использования, а также те, о которых я ещё не подумал. Вместо этого появилась идея разработать библиотеку, которая с минимальными усилиями позволяет разработчику самому реализовать те варианты ипользования, которые ему нужны, причем именно так, как он себе и представляет идеальным образом. Обрати внимание, что когда был надан вопрос на счет атрибутов мне было не лень продемонстрировать всего несколько строчек кода, реализующие мэппинг через атрибуты. Собственно для этого библиотека и создавалась.

IT>Как раз как маппер, в реальных сценариях BLT даст фору кому угодно.

Смотря на каких сценариях. Если это сценарии связанные с БД, то скорее всего да, ведь он именно на эти сценарии и заточен. Если же рассматривать сценарии Object2Object, то уже вряд ли, так как БЛТ сильно уступает конкурентам по функционалу и количеству покрываемых вариантов использования.

IT>"Даже вложенные объекты" в BLT не поддерживаются по-умолчанию. Кстати, они не поддерживаются по-умолчанию практически нигде,

Ну почему же, AutoMapper поддерживает, и многие другие Object2Object mapping библиотеки поддерживают. Я бы даже сказал, что большинство из них.

IT>т.к. это вызывает больше проблем, чем бенефитов.

Все проблемы решаемы.

IT>Научить BLT справляться с поставленной задачкой можно, например, следующим образом:


IT>
IT>[MapField("str2", "i.str2")]
IT>public class Destination
IT>{
IT>    public class Int
IT>    {
IT>        public string str2;
IT>    }

IT>    public string str1;
IT>    public Int i = new Int();
IT>}

IT>[MapField("str2", "i.str2")]
IT>public class Source
IT>{
IT>    public class Int
IT>    {
IT>        public string str2 = "B1::Int::str2";
IT>    }

IT>    public string str1 = "B1::str1";
IT>    public Int i = new Int();
IT>}
IT>


Ну, это уже "закат солнца вручную". Если уж нет автоматики, не проще ли тогда вообще написать:
Destination.i.str2 = Source.i.str2;

Тут по крайней мере и интеллисенс есть и компилятор ошибки проверит.

IT>Думаю, любому взрослому и умному человеку, заинтересованному в конечном результате, обязательно захотелось бы найти объснению такому чудовищному отставанию в производительности и разобраться что же происходит на самом деле,

Ну это очевидно, я же выше по теме написал из-за чего разница в производительности.

IT>а не отмазываться фразами вроде "Дак это проблемы BLT. Он другого интерфейса не предоставляет.". Тем более, что и интерфейс такой у BLT есть

Как это есть? Ты же сам пишешь, что:

API для получения мэппера как это происходит в сценарии в BLT попросту отсутствует.


IT>и у EM есть интерфейс, который поставил бы библиотеки в одинаковые условия. И тогда 250 раз мгновенно уменьшились бы на 125. Хотя проблема, конечно, не в этом.


А зачем их ставить в одинаковые условия? Это примерно как при сравнении производительности бейсика и С++ код на С++ интерпретировать дабы поставить их в одинаковые условия и тем самым доказать, что бейсик не медленее С++.

EmitMapper проектировался в первую очередь как Object2Object mapper. В этом случае схемы данных источников и получателей известны заранее и нет проблемы с тем, чтобы создать конфигурацию мэппера под конкретные схемы данных заранее (например при старте программы) и затем её только использовать. Посмотри выше по теме здесь
Автор:
Дата: 30.12.09
- человек именно так и делает.

IT>Сценариев где нужен маппинг одного объектв в другой не так много, высокопроизводительных сценариев ещё меньше, а когда они реально возникают, то написать код вручную, особенно сегодня при наличии инициализаторов в C# не представляет особой сложности.


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

IT>В общем, BLT под такие сценарии никогда не оптимизировался. Другое дело вот такие сценарии:


IT>
IT>...
IT>

IT>Здесь мы уже имеем разницу не в 250 раз, а около двух, хотя и не в пользу BLT.
У меня получается разница в 4-5 раз. Ну да неважно, это уже более-менее сравнимо.

IT>Оставшаяся разница объясняется тем, что BLT делает больше проверок в рантайм. Например, если изменить приведённый выше код следующим образом, то EM упадёт:


IT>
IT>public class B2
IT>{
IT>    ...
IT>    public decimal? n5 = null;
IT>    ....
IT>}
IT>


И это очень зря, что БЛТ проглотил данную явно ошибочную ситуацию. Что он поставит вместо null? 0? А почему не -1 или не 42?
EM поддерживает NullSubstitution и с помощью следующей конфигурации можно создать мэппер, который вместо null будет писать 42:
var mapper = ObjectsMapperManager.DefaultInstance.GetMapper<B2, A2>(
        new DefaultMapConfig().NullSubstitution<decimal?,int>( state => 42 )
    );

Этот мэппер уже не падает.

IT>Некоторые из этих проверок можно сократить только генерацией кода под каждый конкретный вариант использования, что практически не имеет смысла если не кешировать каким-то образом сам вариант использования или явно не напрягать пользователя, что бы он его как-то идентифицировал. В приведённых выше тестах EM именно этим и занимается.


К сожалению, без этого нелься сделать сколько-нибудь гибкий мэппер.

IT>Это хорошо работает с объектами, но не работает с источниками данных, структура которых становится известной только в момент выполнения. К таким источникам относятся, например, базы данных.


Согласен.

IT>Кстати, давайте посмотрим что у нас с базами данных:

IT>
IT>...
IT>

IT>В этом примере EM уже начинает отставать.
Верно, но после маленькой оптимизации (заменил DbDataReader[String] на DbDataReader[Int]) EM уже начал обгонять BLT.

IT>Скорее всего reader.ToObjects, взятый из примеров библиотеки не очень хорош.

Во-первых, EM — это не про базы данных. Конфигурация мэппера для дадатидера была показана для примера. Во-вторых, отставание было на считанные проценты на синтетическом примере, при котором вызов "SqlCommand.ExecuteReader" по результатам профилирования составляет всего 4% от общего времени работы программы. В-третьих это уже поправлено

IT>При этом он не очень хорош будучи написанным самим автором библиотеки, а что будет написано, если будет, пользователями, плохо знакомыми как с самой библиотекой, так и с базами данных?


Ничего страшного не случилось бы. Если для кого-то несколько процентов в абсолютной разнице в производительности между DbDataReader[String] и DbDataReader[Int] очень существенны, то, возможно, вместо базы данных следовало бы использовать что-то другое? (потому как судя по всему СУБД простаивает без дела).

IT>Ну и в заключении, вот такие примеры в качестве сценарии использования библиотеки из документации лучше убрать:


IT>
IT>public DTOCustomer GetCustomer(Guid customerId)
IT>{
IT>    using (var dc = new DataContext())
IT>    {
IT>        var customer = dc.Customers.Where(c => c.CustomerID == customerId).Single();
IT>        return ObjectsMapperManager.DefaultInstance.GetMapper<Customer, DTOCustomer>().Map(customer);
IT>    }
IT>}
IT>


А что с ним не так?

IT>И в самом самом заключении, ObjectsMapperManager — это немного не по-английски.

Ок
лэт ми спик фром май харт
Re[6]: [ANN] Emit Mapper
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.01.10 12:34
Оценка:
Здравствуйте, IT, Вы писали:

IT>Что нужнее, DML или SL?


DML
... << RSDN@Home 1.2.0 alpha 4 rev. 1331 on Windows 7 6.1.7600.0>>
AVK Blog
Re[3]: [ANN] Emit Mapper
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.01.10 12:34
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>1) Стратегия "Рыба". Предугадать возможные варианты использования и реализовать под них готовую функциональность. (это как раз то, о чем ты говоришь)

T>2) Стратегия "Удочка". Предоставив пользователю интерфейс с помощью которого он может самостоятельно добиться желаемого результата. Тем самым автоматически покрывается большинство вариантов использования и даже те из них, о существовании которых автор библиотеки даже не подозревает.

Правильная стратегия — рыба для публично доступного ядра и удочка для набора функционала вокруг. Именно по такой схеме построен BLT.
... << RSDN@Home 1.2.0 alpha 4 rev. 1331 on Windows 7 6.1.7600.0>>
AVK Blog
Re[4]: [ANN] Emit Mapper
От: mrTwister Россия  
Дата: 04.01.10 12:51
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Правильная стратегия — рыба для публично доступного ядра и удочка для набора функционала вокруг. Именно по такой схеме построен BLT.


Вопрос только в объеме рыбы и простоте и доступности удочек.
лэт ми спик фром май харт
Re[5]: [ANN] Emit Mapper
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.01.10 14:41
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Вопрос только в объеме рыбы


Ядро у BLT довольно маленькое.

T> и простоте и доступности удочек.


А это вовсе не вопрос, потому что проблемы с конкретной удочкой вполне решаемы написанием собственной удочки в крайнем случае.
... << RSDN@Home 1.2.0 alpha 4 rev. 1333 on Windows 7 6.1.7600.0>>
AVK Blog
Re[6]: [ANN] Emit Mapper
От: mrTwister Россия  
Дата: 04.01.10 15:01
Оценка: +2
Здравствуйте, AndrewVK, Вы писали:

AVK>А это вовсе не вопрос, потому что проблемы с конкретной удочкой вполне решаемы написанием собственной удочки в крайнем случае.



Прекрасно. Сколько надо написать кода для маппинга вложенных структур (в том числе рекурсивных)?
лэт ми спик фром май харт
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.