Raja Ganapathy Ответов: 5

Как увеличить скорость выполнения времени?


for (int i = 0; i < ds.Tables[s].Rows.Count; i++)
{
    for (int j = 0; j < ds.Tables[s].Columns.Count; j++)
    {
        if (ds.Tables[s].Rows[i][j].ToString().ToUpper().Trim().Contains("NO OF UNITS"))
        {

            int t = j + 1;
            if (ds.Tables[s].Rows[i][t].ToString() == "")
            {
                dt.Rows.Add();
                dt.Rows[mn][0] = "Parts Per uint Should be mandatory";
                mn = mn + 1;
            }

        }

    }
}


В приведенном выше коде я буду использовать функцию "Contains" для проверки таблицы данных.проблема в том, что процесс выполнения этого метода очень медленный.как это исправить.
Примечание:
В этой таблице есть несколько строк и столбцов.и заголовок (заголовок или описание типа " номер товара")
Положение заголовков строк и столбцов не фиксировано, оно изменяется в зависимости от листа, поэтому только я использовал функцию "содержит". более 10 циклов для этой проверки.так что процесс идет очень медленно.

Как это исправить.

Что я уже пробовал:

for (int i = 0; i < ds.Tables[s].Rows.Count; i++)
        {
            for (int j = 0; j < ds.Tables[s].Columns.Count; j++)
            {
                if (ds.Tables[s].Rows[i][j].ToString().ToUpper().Trim().Contains("NO OF UNITS"))
                {

                    int t = j + 1;
                    if (ds.Tables[s].Rows[i][t].ToString() == "")
                    {
                        dt.Rows.Add();
                        dt.Rows[mn][0] = "Parts Per uint Should be mandatory";
                        mn = mn + 1;
                    }

                }

            }
        }

Я использовал этот код.

Andy Lanng

Вы слышали о linq? Это могло бы, по крайней мере, упростить код, в лучшем случае улучшить время выполнения

Raja Ganapathy

Как это сделать, сэр.

F-ES Sitecore

Linq не улучшает производительность, во всяком случае, он будет замедлять ее еще больше. Linq - это удобство, а не скорость.

F-ES Sitecore

Первое, что я бы попробовал, - это избавиться от ToUpper, ToString и Trim и использовать нечувствительный к регистру IndexOf, а не Contains

http://stackoverflow.com/questions/444798/case-insensitive-containsstring

культура.CompareInfo.IndexOf ((string) ds.Таблицы[s]. строки[i][j], "нет единиц измерения", CompareOptions.Параметром ignorecase) != -1

Непроверенный, но что-то вроде этого

Raja Ganapathy

Спасибо вам всем!

5 Ответов

Рейтинг:
5

Philippe Mori

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

Таким образом, лучшим решением было бы преобразовать базу данных один раз, а затем использовать ее в новом формате как для запросов, так и для добавления новых материалов.

Если база данных удалена и нужно вернуть только несколько строк, то фильтрация в основном на сервере очень поможет.

Если вам действительно приходится обрабатывать много неструктурированных данных, то, вероятно, лучше всего использовать SQL-ридер для такого рода кода.

Если вам нужна производительность, то научитесь правильно проектировать базу данных и писать эффективные запросы.


Raja Ganapathy

Спасибо всем!

Рейтинг:
20

PureNsanity

Шаг 1-распараллелить обработку

            var bag = new ConcurrentBag<tuple><int,>>();

            Parallel.For(0, ds.Tables[s].Rows.Count, (i) =>
            {
                for (int j = 0; j < ds.Tables[s].Columns.Count; j++)
                {
                    if (ds.Tables[s].Rows[i][j].ToString().ToUpper().Trim().Contains("NO OF UNITS"))
                    {

                        int t = j + 1;
                        if (ds.Tables[s].Rows[i][t].ToString() == "")
                        {
                            bag.Add(new Tuple<int,>(i, j));
                        }
                    }
                }
            });
</tuple>


Шаг 2-Выполните массовую операцию

var indexes = bag.ToList();

// Do a bulk operation


То, как вы выполняете массовую операцию, в значительной степени зависит от того, какой сервер БД вы используете и как вы хотите подключиться к данным локально. Вставлять по одному очень дорого... Если ваш DataTable полностью отключен, вы можете просто последовательно добавлять их.

Шаг 3-лучше спроектируйте базу данных

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


Рейтинг:
2

OriginalGriff

Начните с того, что получите это правильно: этот код выдаст ошибку индекса вне диапазона, если последний столбец содержит вашу строку, так как внутренний цикл использует j от 0 до (columns count - 1), а код использует j + 1 для доступа к столбцу.
Это означает, что последний столбец не нуждается в проверке, так что это экономит некоторые итерации внутреннего цикла.
Проверьте, какие еще ячейки нужно проверить - скорее всего, только одна или две, и это значительно сократит количество итераций. Просмотр ваших данных и разработка того, что действительно необходимо, окажет наибольшее влияние на время выполнения.

И имейте в виду, что Linq все еще является циклом - он просто скрыт, поэтому выполнение откладывается до тех пор, пока вы не "свернете форму сигнала", получив результаты.


Рейтинг:
12

Andy Lanng

Хорошо , я дам вам очень быструю версию.

У вас уже должен быть доступен linq, если вы используете какую-либо последнюю версию visual studio. Возможно,вам даже не придется добавлять ссылку using.

Linq-это синтаксис запросов, используемый .net для упрощения циклов, подобных тому, который вы показали выше.

Я использую синтаксис расширения linq, так что это то, что я покажу вам здесь. Другие предпочитают синтаксис запроса, поэтому вы всегда можете получить помощь в переводе с одного языка на другой.


Нет, этот запрос довольно сложный, так что голый со мной

ds.Tables[s].Rows 
    .Cast<datarow>() 
    
var columns = ds.Tables[s].Columns.Cast<datacolumn>().Count();
ds.Tables[s].Rows//these are not currently queriable so we have to cast them out
   .Cast<datarow>() //this is only needed with collections 
   .Where(   //we want to bring back only rows that match the conditions
      dr =>  //this represents a single row
             //The rest of this is lambda.  thing of 'dr' as a parameter and the rest as a function (not entirely true) 
      {
         int i = //get the index of the "NO OF UNITS" item
           dr.ItemArray  //the columns in the row
           .Select((item, index) => new {item, index})  //we need the index so select an anon object
           .Where(  //select only the cell we want
               n => // n represents a class{item = object, index = int} that we just created
               n.item.ToString().ToUpper().Contains("NO OF UNITS") && //check the value
               (n.index + 1) < columns)  //check it's not the last column
               .Select(n => n.index + 1)  //select the next index
               .FirstOrDefault(); will return zero if conditions are not met 
           return i != 0 && string.IsNullOrEmpty(dr.ItemArray[i].ToString());
           // return false if index is zero or next item in not empty.
           //We must return a boolean to the "Where" clause.
     })
   //Now we have our rows.  You can do what you like.  Select any detail you want from the row or just create new rows in dt
   .Select(r=>);

</datarow></datacolumn></datarow>



Это довольно продвинутый linq & lambda.
Я знаю, что у тебя будет куча вопросов по этому поводу. ^_^


Andy Lanng

ТБХ - я бы согласился с тем, что говорят другие ребята - они знают о производительности гораздо больше, чем я когда-либо знал

Philippe Mori

Использование Linq подобным образом, безусловно, не поможет оптимизировать код. Linq иногда может помочь для SQL-запросов, так как он может генерировать оптимизированные запросы. Но здесь это не очень поможет, так как OP не имеет данных в предопределенных столбцах. Тем не менее, если база данных удалена и требуется извлечь только несколько строк, это может помочь.

Andy Lanng

Это в значительной степени исключительно то, как я его использую, поэтому вполне понятно, что мой опыт предвзят. Спасибо за разъяснение ^_^

Рейтинг:
0

Patrice T

Я думаю, что лучше всего вложить немного мозгов в ваш код.
Я думаю ds является результатом запроса в базе данных и что NO OF UNITS не разбросано в каждой колонне.
Обнаружение того, какие столбцы могут содержать эту строку, значительно улучшит время выполнения.

Можно смело снимать Trim() из кода.