Как улучшить скорость универсального цикла при чтении из базы данных - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть функция отображения, которая читает данные, загруженные из базы данных.Он отображается на класс через общий.

Проблема в том, что для цикла 10000 записей требуется 3 минуты.Я хотел бы улучшить его производительность Я ищу решение для этого?

public static List<T> GetList<T>(string query = null, string whereClause = null, Dictionary<string, string> Params = null)
{
        var results = new List<T>();
        var properties = GetReadableProperties<T>();
        query = QueryMaker.SelectQuery<T>(query, whereClause);

        using (SqlConnection Connection = new SqlConnection(ConnectionString))
        {
            Connection.Open();
            SqlCommand cmd = GetSqlCommandWithParams(query, Connection, Params);
            SqlDataReader reader = cmd.ExecuteReader();

            if (reader.HasRows)
            {
                // From here 
                while (reader.Read())
                {
                    var item = Activator.CreateInstance<T>();

                    foreach (var property in properties)
                    {
                        DBReader(item, property, reader);
                    }

                    results.Add(item);
                }

                // To here. It takes 3 minutes. reading a 10000 record from database into reader isn't as slow as this code is.
            }

            Connection.Close();
            return results;
        }
}

Это функция DBReader:

private static void DBReader(Object _Object, PropertyInfo property, SqlDataReader reader)
{
        if (!reader.IsDBNull(reader.GetOrdinal(property.Name)))
        {
            Type convertTo = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
            property.SetValue(_Object, Convert.ChangeType(reader[property.Name], convertTo), null);
        }
        else
        {
            property.SetValue(_Object, null);
        }
}

1 Ответ

0 голосов
/ 07 февраля 2019

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

  • сохранить результат GetOrdinal для повторного использования при получении значений.
  • использовать универсальный new() вместо Activator.CreateInstance.
  • Вместо использованияотражение, вы можете предварительно скомпилировать выражение в Func<> и вызывать его для каждой строки.
  • Вызвать соответствующие Get...() методы, основанные на желаемом типе, чтобы избежать упаковки и распаковки.

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

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