Оптимизация программы с использованием ThreadPool. C # - PullRequest
2 голосов
/ 09 января 2012

С этим кодом вожусь очень много, в нем долго ковырялся, чтобы он работал стабильно и быстро.Но не может ускорить его.Это медленно ...

for (int jrCnt = rCnt; jrCnt <= arrayTable.GetUpperBound(0); jrCnt++)
{
    var prcI = new Price();

    /* here is the code search and add data to prcI */

    if ((!string.IsNullOrEmpty(prcI.name)) && (prcI.prc != 0))
    { // function add

        /* adding more information to prcI */

        ThreadPool.QueueUserWorkItem(delegate
        {
            if (!Accessor.AddProductUpdateProduct(prcI)) _updateCounter++;
            _countadd++;
        }); // I put the longest function in the streams
    }
}

Здесь мы вызываем функцию.Работает долго, даже с пулом потоков.

public static bool AddProductUpdateProduct(Price price)
{
   using (var db = new PriceDataContext())
        {
            var matchedprod =
                db.Price.Where(x => x.name == price.name && x.company == price.company && x.date != price.date);

            if (matchedprod.Select(x=>x).Count() > 1)
            {
                db.Price.DeleteOnSubmit(matchedprod.First());
                db.SubmitChanges();
            }

            var matchedproduct = matchedprod.SingleOrDefault();

            if (matchedproduct != null)
            {
                matchedproduct.date = price.date;
                matchedproduct.prc = price.prc;

                db.SubmitChanges();
                return false;
            }
        }


/*here the code to add the product to the database.*/
return true;
}

Подскажите пожалуйста, как ускорить работу с пулом потоков?

Ответы [ 3 ]

3 голосов
/ 09 января 2012

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

Однако в этом случае это не поможет. Это ваши запросы LINQ, которые имеют недостатки. Включить отладку . Посмотрите на сгенерированный SQL и исправьте его.

Во-вторых

if (matchedprod.SingleOrDefault() != null)
{
    matchedprod.SingleOrDefault().date = price.date;
    matchedprod.SingleOrDefault().prc = price.prc;

    db.SubmitChanges();
    return false;
}

Это будет запрашивать базу данных три раза. Один раз за звонок в SingleOrDefault. Выполните один запрос и сохраните результат в переменной.

Третий

В чем разница между matchedprod и matchedprodDel? Запросы для них равны?

Forth

Это легче читать:

var matchedprod = db.Price.Where(x => x.name == price.name && x.company == price.company && x.date != price.date)
2 голосов
/ 09 января 2012

Работает долго, даже с пулом потоков.

Заблуждение. Если метод занимает 10 секунд, он занимает 10 секунд в и из потока. Поток не может магически улучшить скорость функции.

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

Теперь я бы начал с вызова - видите, у вас есть некоторый SQL, который не должен выполняться более миллисекунды, поэтому, если он медленный, я могу предложить либо перегруженное оборудование, либо какой-то не очень умный человек, не знающий что такое индекс, делающий операторы SQL очень-очень медленными?

Также обратите внимание, что пул потоков, если он не был предварительно настроен, МЕДЛЕННО наращивает потоки - как я думаю, по одному в секунду. Так что, если вы много в очереди ... вы мертвы.

Наконец, почему, черт возьми, вы используете пул потоков, а не библиотеку задач? Это не так уж и ново .... и имеет более приятный API и больший контроль над потоками.

И, наконец, используйте профилировщик, чтобы узнать, на что тратится время. Это не так сложно. Программирование без профилировщика - это все равно что пытаться готовить, не нагревая ничего - вы ограничены в том, что вы делаете Профессиональный повар? Используйте профессиональные инструменты.

0 голосов
/ 09 января 2012

Обычно ускорение кода сначала включает использование так называемого " Profiler ". Это инструмент, который на самом деле измеряет производительность вашего кода (вплоть до уровня строки исходного кода).

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

Поэтому я предлагаю вам сначала использовать профилировщик, лично я использую ANTS Performance Profiler (14-дневная бесплатная пробная версия), чтобы обнаружить ваши медленно работающие строки кода.

...