Информация об изменениях

Сообщение Re[51]: MS забило на дотнет. Питону - да, сишарпу - нет? от 05.09.2021 18:57

Изменено 05.09.2021 21:02 vdimas

Re[51]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Sinclair, Вы писали:

V>>Так я попросил показать, что это за код, где живет, который

V>>
V>>GetFieldType(i) == typeof(int)
V>>      ? MemoryMarshal.GetReference(MemoryMarshal.Cast<byte, int>(_rawData.Slice(GetFieldOffset(i)));
V>>      : Convert.ToInt32(GetValue(i));
V>>

S>Примерно такой код и живёт

Так где?


V>>И да, если читать из поля Int16, например, Int32, то опять пляшем через боксинг, верно?

S>Смотря как делать. Но это — не очень важный аспект: поля int16 в базах встречаются нечасто.

Торговля.


S>А там, где встречаются, разработчики знают, зачем их применяют, и не будут делать конверсию на том конце, который сделает её медленнее.


На "том конце" выгодней использовать In32 или даже UIn32, в случае которого опять боксинг, согласно приведённого кода.

V>>Ну так из приемного буфера (который уже managed) — в MemoryRecordBuffer, а оттуда в датасет или в поля объектов какого-нить ORM.

S>Вот не вижу этого момента "из приёмного буфера".

Я приводил и сниппеты и ссылки дотнетного ODBC-драйвера, вернись да посмотри.


V>>>>И в любом случае твой пример только для MSSQL, а для любых других баз на основе OLEDB или ODBC будет как я дал ссылку на исходники дотнета.

S>Для любых других баз будет их собственные реализации IDataRecord.

В которых всё не лучше:
https://github.com/mysql/mysql-connector-net/blob/502d718bed8ca9cf81a3a0397574f24ec41b25ba/MySQL.Data/src/datareader.cs#L619
   public override Int32 GetInt32(int i)
    {
      IMySqlValue v = GetFieldValue(i, true);
      if (v is MySqlInt32)
        return ((MySqlInt32)v).Value;

      return (Int32)ChangeType(v, i, typeof(Int32));
    }



V>>И все пишут в своих проектах собственные дрова к БД?

V>>Или пользуются имеющимся в дотнете?
S>Зачем собственные? Зачем имеющиеся в дотнете? Если есть такая потребность — пишется один раз эффективная реализация для конкретной СУБД.

Это умозрительно.
Речь о том, как по-факту.


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


Но можешь взять и не что попало.
А в дотнете не можешь.


V>>Куда я тебе показал в первый раз — это реализация ODBC драйвера.

V>>Все базы имеют ODBC-дрова, но далеко не все имеют OLEDB.
V>>Например, нет OLEDB драйвера к самой популярной в вебе базе MySQL.
S>Эмм, причём тут OLEDB? Мы же вроде бы про дотнет говорим.

Потому что под виндами самая популярная технология доступа к БД, почти все базы, доступные под Windows, имели ODBC и OLEDB-драйверы.
ODBC легковеснее, но сложнее в использовании.
OLEDB проще, т.к. это некая объектная модель на основе COM.


S>Это же COM — значит, никакого инлайнинга вызовов GetData; да и сигнатура у его методов подразумевает копирование в caller-allocated storage.


Ага.


S>Ну, и где тут хвалёный С++ с его возможностью "вернуть сразу данные из буфера без промежуточных копирований"?


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


S>Так что давайте мы не будем рассматривать OLE DB в качестве какой-то особенно быстрой альтернативы дотнету.


Откуда ты взял "альтернативу"?
Никакой альтернативы. ))

Дотнетный ADO.Net — это изначально обертка над нейтивными ODBC и OLEDB.
Даже которая была изначально оберткой над MS SQL Native Client — там тоже обертка над OLEDB-подключением была.

Речь о кач-ве этой обертки.


S>А если мы посмотрим на дотнет, то есть, к примеру, System.Data.Sqlite.org.


Это локальная база, в основном.


V>>Следующая по популярности идёт PostgreSQL, к ней тоже живые/актуальные только ODBC-дрова.

S>Для PostgreSQL живы/актуальны нативные дотнетные дрова, 100% написанные на C#. Судя по всему — тоже не очень плохо написанные: https://www.npgsql.org/

Лень смотреть еще и на Postgre-дрова, но вот для MySQL ссылку привёл — мрак.


V>>Я говорил как оно есть по-факту, а ты рассуждаешь как оно могло бы быть, если бы все в мире действовали самым разумным способом.

S>Как видим, все действуют именно так, как я говорю.

Ложь.
Причём, ложь глупая, игнорующая реальность.


V>>"В нейтиве оптимизированные" — это ты только что придумал.

V>>Дрова там обычные, бо парсить разметку любого протокола много ума не надо.
V>>Оптимизированным получается сам сценарий зачитки данных, потому что максимально непосредственный.
S>Непонятно. Вы в качестве оптимизированного сценария приводите почему-то OLEDB, который by design страдает от тех же (и худших) ограничений, что и дотнет.

Нет, не страдает.
Страдаешь ты непонимаем той простой вещи, что зачитка данных и вообще задачи драйвера БД — это такие же задачи как сериализации-десериализации.

И что если (допустим) кто-то где-то навертел слои абстракций, то и обходить их надо как принято — через IoC.

Сравни poll-метод в случае "матрёшки" абстракций:

class Layer1Obj {
    public virtual int GetInt32(int index) {}
}

class Layer2Obj {
    Layer1Obj _obj1;

    public virtual int GetInt32(int index) {
        return _obj1.GetInt32(int index);
    }
}

...

class Layer10Obj {
    Layer9Obj _obj9;

    public virtual int GetInt32(int index) {
        return _obj9.GetInt32(int index);
    }
}


С принятым в OLEDB подходом с акцессорами, когда акцессоры устанавливаются на текущий recordset и одной командой вызываются все они.

В дотнете можно сравнить с подпиской на события:
class Layer10Obj {
    Layer9Obj _obj9;

    public event SomeEventSignature SomeEvent {
        add { _obj9 += value; }
        remove { _obj9 -= value; }
    }
}


IoC-подход "прошивает" слои абстракции.
Так работает OLEDB.


V>>Там должно было быть до 80% общего кода, если не больше.

S>Со временем, может быть, и будет.

Еще через 20 лет? ))


S>А может быть — нет. Потому что какой-нибудь SQLite вообще буфера клиенту не отдаёт — зачем ему? У него все манипуляции делаются прямыми вызовами в inproc DLL.


У многих драйверов так делается.
Речь о том, что код этот глупейший.
Банальную задачу сериализации/десериализации ни сформулировать не могут, ни решить.

Как ни крути, но в плане доступа к БД над дотнетом как проклятие висит.
Днище.


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


Да пофик.
Когда речь о десериализации тела сообщения с данными, то там всё очень близко — данные идут подряд согласно схеме рекордсета и битового вектора NULL-значений.
Иногда с учётом выравнивания, но это уже совсем мелочи в различиях, т.е. код десериализации под 99% баз мог быть очень близок.
И предлагать модель эффективной десериализации.

На сегодня не предлагает.

Забавно еще то, что ADO хотя и унаследовало от COM ADODB аббревиатуру, но не унаследовала принципы работы, бо ADODB — это IDispatch-реализации прямо поверх OLEDB, т.е. для возможности использовать OLEDB из скриптовых языков (например, для VBA, хотя для VB IDIspatch уже не нужен, он может пользовать OLEDB напрямую).

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

И твои попытки оправдать всё это днище через игнор фактического положения вещей или даже через прямую ложь — такое же днище.


S>Если мы захотим сделать что-то более оптимальное, чем дефолтный драйвер поверх универсального коннектора типа OLE DB или ODBC, то придётся погрузится вот в эти подробности.


Ой, уже страшно...
Аж протокол распарсить...
Неподъёмного веса задача. ))
Ты хоть себя слышишь?



V>>Ну вот я тебе ссылку дал на кишки драйвера к MSSQL.

V>>Это я уже молчу о том, что половину типов по той ссылке можно было сделать value-type.
S>В теории — да.
V>>По-факту там ад и ужас, нагрузка на GC на ровном месте.
S>По факту там внутри — массив структур.

Опять глупая ложь. ))
Ладно, надоело.
Днище.
Re[51]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Sinclair, Вы писали:

V>>Так я попросил показать, что это за код, где живет, который

V>>
V>>GetFieldType(i) == typeof(int)
V>>      ? MemoryMarshal.GetReference(MemoryMarshal.Cast<byte, int>(_rawData.Slice(GetFieldOffset(i)));
V>>      : Convert.ToInt32(GetValue(i));
V>>

S>Примерно такой код и живёт

Так где?


V>>И да, если читать из поля Int16, например, Int32, то опять пляшем через боксинг, верно?

S>Смотря как делать. Но это — не очень важный аспект: поля int16 в базах встречаются нечасто.

Торговля.


S>А там, где встречаются, разработчики знают, зачем их применяют, и не будут делать конверсию на том конце, который сделает её медленнее.


На "том конце" выгодней использовать In32 или даже UIn32, в случае которого опять боксинг, согласно приведённого кода.

V>>Ну так из приемного буфера (который уже managed) — в MemoryRecordBuffer, а оттуда в датасет или в поля объектов какого-нить ORM.

S>Вот не вижу этого момента "из приёмного буфера".

Я приводил и сниппеты и ссылки дотнетного ODBC-драйвера, вернись да посмотри.


V>>>>И в любом случае твой пример только для MSSQL, а для любых других баз на основе OLEDB или ODBC будет как я дал ссылку на исходники дотнета.

S>Для любых других баз будет их собственные реализации IDataRecord.

В которых всё не лучше:
https://github.com/mysql/mysql-connector-net/blob/502d718bed8ca9cf81a3a0397574f24ec41b25ba/MySQL.Data/src/datareader.cs#L619
   public override Int32 GetInt32(int i)
    {
      IMySqlValue v = GetFieldValue(i, true);
      if (v is MySqlInt32)
        return ((MySqlInt32)v).Value;

      return (Int32)ChangeType(v, i, typeof(Int32));
    }



V>>И все пишут в своих проектах собственные дрова к БД?

V>>Или пользуются имеющимся в дотнете?
S>Зачем собственные? Зачем имеющиеся в дотнете? Если есть такая потребность — пишется один раз эффективная реализация для конкретной СУБД.

Это умозрительно.
Речь о том, как по-факту.


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


Но можешь взять и не что попало.
А в дотнете не можешь.


V>>Куда я тебе показал в первый раз — это реализация ODBC драйвера.

V>>Все базы имеют ODBC-дрова, но далеко не все имеют OLEDB.
V>>Например, нет OLEDB драйвера к самой популярной в вебе базе MySQL.
S>Эмм, причём тут OLEDB? Мы же вроде бы про дотнет говорим.

Потому что под виндами самая популярная технология доступа к БД, почти все базы, доступные под Windows, имели ODBC и OLEDB-драйверы.
ODBC легковеснее, но сложнее в использовании.
OLEDB проще, т.к. это некая объектная модель на основе COM.


S>Это же COM — значит, никакого инлайнинга вызовов GetData; да и сигнатура у его методов подразумевает копирование в caller-allocated storage.


Ага.


S>Ну, и где тут хвалёный С++ с его возможностью "вернуть сразу данные из буфера без промежуточных копирований"?


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


S>Так что давайте мы не будем рассматривать OLE DB в качестве какой-то особенно быстрой альтернативы дотнету.


Откуда ты взял "альтернативу"?
Никакой альтернативы. ))

Дотнетный ADO.Net — это изначально обертка над нейтивными ODBC и OLEDB.
Даже которая была изначально оберткой над MS SQL Native Client — там тоже обертка над OLEDB-подключением была.

Речь о кач-ве этой обертки.


S>А если мы посмотрим на дотнет, то есть, к примеру, System.Data.Sqlite.org.


Это локальная база, в основном.


V>>Следующая по популярности идёт PostgreSQL, к ней тоже живые/актуальные только ODBC-дрова.

S>Для PostgreSQL живы/актуальны нативные дотнетные дрова, 100% написанные на C#. Судя по всему — тоже не очень плохо написанные: https://www.npgsql.org/

Лень смотреть еще и на Postgre-дрова, но вот для MySQL ссылку привёл — мрак.


V>>Я говорил как оно есть по-факту, а ты рассуждаешь как оно могло бы быть, если бы все в мире действовали самым разумным способом.

S>Как видим, все действуют именно так, как я говорю.

Ложь.
Причём, ложь глупая, игнорующая реальность.


V>>"В нейтиве оптимизированные" — это ты только что придумал.

V>>Дрова там обычные, бо парсить разметку любого протокола много ума не надо.
V>>Оптимизированным получается сам сценарий зачитки данных, потому что максимально непосредственный.
S>Непонятно. Вы в качестве оптимизированного сценария приводите почему-то OLEDB, который by design страдает от тех же (и худших) ограничений, что и дотнет.

Нет, не страдает.
Страдаешь ты непонимаем той простой вещи, что зачитка данных и вообще задачи драйвера БД — это такие же задачи как сериализации-десериализации.

И что если (допустим) кто-то где-то навертел слои абстракций, то и обходить их надо как принято — через IoC.

Сравни poll-метод в случае "матрёшки" абстракций:

class Layer1Obj {
    public virtual int GetInt32(int index) {}
}

class Layer2Obj {
    Layer1Obj _obj1;

    public virtual int GetInt32(int index) {
        return _obj1.GetInt32(int index);
    }
}

...

class Layer10Obj {
    Layer9Obj _obj9;

    public virtual int GetInt32(int index) {
        return _obj9.GetInt32(int index);
    }
}

Сравнить надо с принятым в OLEDB подходом с акцессорами, когда акцессоры устанавливаются на текущий recordset и вызываются одной командой.

В дотнете такой подход можно сравнить с подпиской на события:
class Layer10Obj {
    Layer9Obj _obj9;

    public event SomeEventSignature SomeEvent {
        add { _obj9 += value; }
        remove { _obj9 -= value; }
    }
}

IoC-подход "прошивает" слои абстракции (бо сам OLEDB — уже абстракция).


V>>Там должно было быть до 80% общего кода, если не больше.

S>Со временем, может быть, и будет.

Еще через 20 лет? ))


S>А может быть — нет. Потому что какой-нибудь SQLite вообще буфера клиенту не отдаёт — зачем ему? У него все манипуляции делаются прямыми вызовами в inproc DLL.


У многих драйверов так делается.
Речь о том, что код этот глупейший.
Банальную задачу сериализации/десериализации ни сформулировать не могут, ни решить.

Как ни крути, но в плане доступа к БД над дотнетом как проклятие висит.
Днище.


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


Да пофик.
Когда речь о десериализации тела сообщения с данными, то там всё очень близко — данные идут подряд согласно схеме рекордсета и битового вектора NULL-значений.
Иногда с учётом выравнивания, но это уже совсем мелочи в различиях, т.е. код десериализации под 99% баз мог быть очень близок.
И предлагать модель эффективной десериализации.

На сегодня не предлагает.

Забавно еще то, что ADO хотя и унаследовало от COM ADODB аббревиатуру, но не унаследовала принципы работы, бо ADODB — это IDispatch-реализации прямо поверх OLEDB, т.е. для возможности использовать OLEDB из скриптовых языков (например, для VBA, хотя для VB IDIspatch уже не нужен, он может пользовать OLEDB напрямую).

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

И твои попытки оправдать всё это днище через игнор фактического положения вещей или даже через прямую ложь — такое же днище.


S>Если мы захотим сделать что-то более оптимальное, чем дефолтный драйвер поверх универсального коннектора типа OLE DB или ODBC, то придётся погрузится вот в эти подробности.


Ой, уже страшно...
Аж протокол распарсить...
Неподъёмного веса задача. ))
Ты хоть себя слышишь?



V>>Ну вот я тебе ссылку дал на кишки драйвера к MSSQL.

V>>Это я уже молчу о том, что половину типов по той ссылке можно было сделать value-type.
S>В теории — да.
V>>По-факту там ад и ужас, нагрузка на GC на ровном месте.
S>По факту там внутри — массив структур.

Опять глупая ложь. ))
Ладно, надоело.
Днище.