. Гидратация объекта .NET из IDataReader низкая производительность - PullRequest
0 голосов
/ 30 марта 2009

Я пытаюсь увлажнить список из ~ 400 бизнес-объектов, и производительность становится очень низкой, когда требуется гидрировать строки. Для гидратации 400 объектов требуется более 20 сек.

EDIT

Мы используем MySQL 5.1 и dotConnect для MySQL v5.0.12 в качестве поставщика данных http://www.devart.com/dotconnect/mysql/

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

Следующий код увлажняет 1 объект за 0 мс

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))

Это также гидратирует 1 объект за 0 мс

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = "FirstName"

Однако, как только я выполняю преобразование объекта datareader в строку, это занимает в среднем 53 мс

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = Convert.ToString(dr("FirstName"))

Я также попробовал увлажнить 2 струны и, как ни странно, это не ухудшило производительность почти так же, как 1 струна? Следующему требуется в среднем 57 мс для увлажнения 1 объекта

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = Convert.ToString(dr("FirstName"))
objUserInfo.LastName = Convert.ToString(dr("LastName"))

Я знаю, что многие люди используют приведенный выше синтаксис для увлажнения бизнес-объектов. Есть ли более эффективный / быстрый способ сделать это?

EDIT Просто сделал еще один тест, который должен был выполнить прямую трансляцию на строку, и она выдает те же медленные скорости :( 53 мс, просто чтобы выполнить приведение.

objUserInfo.FirstName = DirectCast("alex", String)

Ответы [ 3 ]

2 голосов
/ 30 марта 2009

Попробуйте:

Вместо

objUserInfo.Firstname = Convert.ToString(dr("FirstName"))

использование

objUserInfo.Firstname = dr.GetString(2);
  1. Используйте методы GetXXX и положитесь на Microsoft, чтобы оптимизировать конвертацию. (Правка: я подозреваю, что Convert.ToString(dr("FirstName")) делает некрасивые неявные и трудоемкие преобразования и / или (не) операции бокса.)
  2. Вместо доступа к столбцу с помощью индексатора строк («FirstName») используйте индексатор чисел (2). Это быстрее, но менее читабельно.

Редактировать: Алекс нашел проблему. Это не проблема кастинга! Его комментарий об этом:

Хорошо, я разобрался с проблемой! Я использую DotNetNuke и заполняю один из его стандартных объектов. Эта проблема является то, что, когда я установил FirstName свойство это делает еще один вызов объект профиля, который есть что на самом деле занимает так много времени! Ничего делать с преобразованием строк или литье.

1 голос
/ 30 марта 2009

Каким провайдером данных вы пользуетесь? У нас была ужасная проблема с оракулом.

Наиболее эффективным будет вызов dr.GetString (columnNumber) - где номер столбца, который вы получаете с помощью dr.GetOrdinal (columnName) (который можно кэшировать в начале цикла чтения).

Однако это не должно быть проблемой. Разве это не может быть размер столбцов?

0 голосов
/ 30 марта 2009

Я также попробовал увлажнить 2 струны и, как ни странно, это не ухудшило производительность почти так же, как 1 струна? Следующее занимает в среднем 57 мс для увлажнения 1 объекта

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

Измерять время следует только после первого цикла (первой гидратации). Таким образом, любая нагрузка на сборку будет производиться до измерения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...