С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
1

Оптимизация кода с массивом

10.12.2013, 17:39. Показов 4025. Ответов 46
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здраствуйте, есть некая программа которую сильно тормозит ниже представленный кусок кода... (для удобства некоторые места заменил конкретными цифрами), считается все это непотребство очень долго для выполняемой задачи
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for (int pye=0; pye<(1103-104+1); pye++)
                {
                   for (int pxe=0; pxe<(1103-104+1); pxe++)
                  {
                    int ert = 0;
                    double summa_FragmentMassiv1 = 0;
                    double summa_FragmentMassiv2 = 0;
                    for (int o=pye; o<(pye+104);o++)
                         {
                            int egb = 0;
             for (int l=pxe; l<(pxe+104);l++)
                {
            summa_FragmentMassiv1+=Massiv1[o,l]*VesPF[ert,egb];
                                  summa_FragmentMassiv2+=Massiv2[o,l]*VesPF[ert,egb];                       
                   egb++;
                }
            ert++;
                   }
                     MassivRandn1[pye,pxe]=summa_FragmentMassiv1;
                     MassivRandn2[pye,pxe]=summa_FragmentMassiv2;
                   
                  }                
                }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.12.2013, 17:39
Ответы с готовыми решениями:

Оптимизация кода
Console.WriteLine(&quot;Нажми Enter для старта...&quot;); // баги: 1. после вывода примера если нажать enter...

Оптимизация кода
Доброй ночи! Подскажите, пожалуйста, или приведите пример как упростить этот код. Программа должна...

Оптимизация кода
Вопрос такой есть ли способ оптимизировать сей код, прибегая к помощи массивов или иными путями?...

Оптимизация кода
Как можно красиво зарефакторить следующий код? int a; int b; ...

46
284 / 255 / 73
Регистрация: 17.07.2012
Сообщений: 618
10.12.2013, 18:17 2
Ну я посмотрел ваш код , насчитал 10000000000 ( 10 миллиардов) операций.
Я решил проверить, запустил вот такой цикл :
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
private static void Main(string[] args)
        {
            Stopwatch sw= new Stopwatch();
            sw.Start();
            for (long pye = 0; pye < 10000000000; pye++)
            {
                int d = 2344*42342;
                int c = 244 * 42342;
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
        }
У меня это заняло...28 секунд.
А у вас там еще много логики. Так что все ок....перепроектируйте.
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
10.12.2013, 18:30  [ТС] 3
Это все понятно но та же самая операция переписанная под матлаб выполняется чуть больше минуты а эта на i7 больше 5 минут

Добавлено через 1 минуту
Чет я не понял что по другому то надо циклы переделать?

Добавлено через 4 минуты
После профилирования в vs2012 видно что 95% от полной
программы занимают 12,14 и 15 строки
0
284 / 255 / 73
Регистрация: 17.07.2012
Сообщений: 618
10.12.2013, 18:39 4
Используйте Parallel.For.
Например, в этом коде на моем рабочем двухядернике вычисления заняли 12 сек:
C#
1
2
3
4
5
6
7
for (long pye = 0; pye < 500; pye++)
   {
       for (long j = 0; j < 10000000; j++)
       {
           int a = 400*753;
       }
    }
а с распарралеливанием 5 сек:
C#
1
2
3
4
5
6
7
Parallel.For(0, 500, x =>
    {
        for (long j = 0; j < 10000000; j++)
        {
            int a = 400 * 753;
        }
    });
0
171 / 120 / 14
Регистрация: 17.06.2013
Сообщений: 386
10.12.2013, 18:42 5
ZaStalim, у вас три вложенных цикла, в каждом из которых порядка 1000 итераций. 1000 в третьей степени дает порядка 1 000 000 000 итераций, что не есть мало. Избегайте вложенности, посмотрите, может можно выполнять итерации с каким то шагом отличным от 1, либо исключить некоторые итерации совсем. Всего одна исключенная итерация на внешнем цикле уменьшит общее количество итераций на 1 000 000
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
10.12.2013, 18:45  [ТС] 6
Тоже думал об этом но надо не запутаться тут
0
171 / 120 / 14
Регистрация: 17.06.2013
Сообщений: 386
10.12.2013, 18:50 7
ZaStalim, а быть может вам и вовсе нужен другой алгоритм. Приведу пример с простыми числами, первое пришедшее в голову очевидное решение так же как и в вашем примере подразумевает большое число итераций, и тормозит на больших числах. Решето эратосфена не является очевидным алгоритмом но сокращает время вычислений в разы. Вывод: если у вас какая то относительно распространенная задача попробуйте нагуглить для нее эффективный алгоритм.
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
11.12.2013, 23:27  [ТС] 8
Есть у кого еще варианты?? Может как-то вообще избавиться от хотя бы 2 циклов
0
foo();
886 / 587 / 222
Регистрация: 03.07.2013
Сообщений: 1,549
Записей в блоге: 2
12.12.2013, 00:39 9
ZaStalim, по Вашему коду не понятно, какую задачу вообще нужно решить. Вы хоть объясните словами, чего Вы хотите в результате
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
12.12.2013, 16:08  [ТС] 10
На словах сложно объяснить по стараюсь схему нарисовать и вечером скинуть

Добавлено через 49 минут
Это дискретная двумерная свертка
0
10 / 25 / 9
Регистрация: 08.12.2013
Сообщений: 115
12.12.2013, 16:40 11
Parallerl.For
Но
summa_FragmentMassiv1+=
это не потокобезопасно, нужно создать массив результатов, а потом в исходном потоке уже посчитать сумму.
Если результаты зависят друг от друга ищи другой алгоритм решения задачи.
0
Grishaco
12.12.2013, 19:49
  #12

Не по теме:


В выдаче гугла по запросу "дискретная двумерная свертка" присутствует преобразования Фурье и описываются частные случаи двумерной и одномерной дискретных сверток.

0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
12.12.2013, 22:26  [ТС] 13
как блин картинку вставить, с радикала вообще не получается
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
12.12.2013, 22:32  [ТС] 14
вот
Миниатюры
Оптимизация кода с массивом  
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
13.12.2013, 08:52  [ТС] 15
Нашел что-то стоящее только на хабре и то там не понятно местами, а так если кто найдет скиньте пожалуйста
0
338 / 327 / 154
Регистрация: 29.10.2012
Сообщений: 949
13.12.2013, 12:03 16
т.е. задача следующая: есть массив размерностью 1103 на 1103 (исходя из примера), необходимо вычислить сумму с произведением элементов входящих в квадрат размерностью 104 на 104 и для всех точек исходного массива куда можно поместить это квадрат 104 на 104, и записать результаты для каждого вычисления в соответствующую ячейку в другом массиве размерностью 1103-104 на 1103-104.
Так?
0
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
13.12.2013, 12:42 17
может вам этот код поможет?
у меня матрицу [1003,1017] с фильтром [4,9] считает чуть меньше минуты
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace _1036069
{
    public class DataElement
    {
        public DataElement(int x, int y, int width, int height)
        {
            X1 = x;
            X2 = x + width;
            Y1 = y;
            Y2 = y + height;
            Width = width;
            Height = height;
        }
 
        public int X1 { get; set; }
        public int X2 { get; set; }
        public int Y1 { get; set; }
        public int Y2 { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        public double Result { get; set; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            int dataWidth = 1003, dataHeight = 1017, filterWidth = 4, filterHeight = 9;
            double[,] data = new double[dataWidth, dataHeight];
            double[,] filter = new double[filterWidth, filterHeight];
            double[,] result = new double[dataWidth, dataHeight];
            Random random = new Random();
            for (var x = 0; x < dataWidth; x++)
                for (var y = 0; y < dataHeight; y++)
                    data[x, y] = Math.Round(random.NextDouble()*10,3);
            for (var x = 0; x < filterWidth; x++)
                for (var y = 0; y < filterHeight; y++)
                    filter[x, y] = Math.Round(random.NextDouble() * 10, 3);
            var dataWidthLimit = dataWidth - filterWidth;
            var dataHeightLimit = dataHeight - filterHeight;
            var dataElements = new List<DataElement>();
            for (var x = 0; x < dataWidthLimit; x++)
                for (var y = 0; y < dataHeightLimit; y++)
                    dataElements.Add(new DataElement(x, y, filterWidth, filterHeight));
            long start = DateTime.Now.Ticks;
            dataElements.AsParallel().ForAll(element =>
                {
                    for (var x=0; x<element.Width;x++)
                        for (var y = 0; y < element.Height; y++)
                            element.Result = element.Result + data[element.X1 + x, element.Y1 + y] / filter[x, y];
                    result[element.X1, element.Y2] = element.Result;
                    Console.WriteLine("{0}, {1}; Result: {2}", element.X1, element.Y1, element.Result);
                });
            long end = DateTime.Now.Ticks;
            Console.WriteLine("Время обработки: {0} сек", new TimeSpan(end - start));
            Console.ReadLine();
        }
    }
}
Добавлено через 4 минуты
Правда я покапался немного в гугле, и выяснил что для дискретной свертки чаще применяют прямое и обратное преобразование фурье, но вот как его адекватно применить я не знаю, если сможете адекватно обьяснить мне математическую часть которая применяется в случае преобразования фурье для дискретной свертки, тогда постараюсь вам помочь

Добавлено через 3 минуты
P. S. забыл добавить у меня процессор Core i5 2500k - 4 ядерник
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
13.12.2013, 13:36  [ТС] 18
Не совсем, необходимый массив получится размерностью 1000х1000 если по схеме посчитать то получиться 10х10 а в исходном варианте 1000х1000

Добавлено через 2 минуты
Было дело получал одномерное преобразование фурье, спектры и т.д. А вот двухмерное и для дискретной свертки чет даже не знаю как
0
10 / 25 / 9
Регистрация: 08.12.2013
Сообщений: 115
13.12.2013, 16:48 19
В каждом подквадрате вычисляется сумма всех его элементов и записывается в массив. Тема для телепатов, к сожалению, большего понять из всей выше писанины не удалось.
Но даже на этом примере видно, что никакие оптимизации не способны изменить общей картины времени выполнения (с числами автора темы, а не теми что в примере ниже), - задача упирается в производительность компьютера.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  static Tuple<int, int, int>[] ArrayIndex(int lengthChild, int lengthInit, out int cres)
        {
            Tuple<int, int, int>[] result = new Tuple<int, int, int>[cres = (int)Math.Pow(lengthInit - lengthChild + 1, 2)];
            for (int i = 0, index = 0, count = 0; i < result.Length; i++,
                new Action(() =>
                {
                    if (index + 1 + lengthChild <= lengthInit) index++;
                    else
                    {
                        index = 0;
                        count++;
                    }
                })()
                )
            {
                result[i] = new Tuple<int, int, int>(count, index, i);
            }
            return result;
        }
 
        static void Main(string[] args)
        {
            //init
            int[,] init = new int[1000, 1000];
            int lengthRectangle = 10;
            Parallel.For(0, 1000, _ =>
            {
                Parallel.For(0, 1000, __ =>
                {
                    init[_, __] = _+__;
                });
            });
 
            //calculation
            Console.WriteLine("start");
            var t = System.Diagnostics.Stopwatch.StartNew();
            int countRectangles;
            var initArray = ArrayIndex(lengthRectangle, init.GetLength(0), out countRectangles);
            long[] sum = new long[countRectangles];
 
            Parallel.ForEach(initArray, index =>
            {
                long sumIn = 0;
                for (int i = index.Item1; i < index.Item1 + lengthRectangle; i++)
                    for (int j = index.Item2; j < index.Item2 + lengthRectangle; j++) sumIn += init[i, j];
                sum[index.Item3] = sumIn;
            }
            );
            t.Stop();
 
            //output
               Console.WriteLine(t.ElapsedMilliseconds+"mc "+initArray.Length+" rectangles");
0
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
13.12.2013, 19:33 20
Hsert, уж простите не смог понять как работает ваш код, слишком все запутанно и не очевидно, но вы ошибаетесь дело еще хуже для TC нужно не просто вычислить сумму каждого подквадрата, ему на каждый подквадрат нужно наложить фильтр, а это как минимум перемножение 2 матриц, ну это если грубо говоря

Добавлено через 2 минуты
Хотя я могу и ошибаться, действительно предоставленный TC кусок кода мало информативен
0
13.12.2013, 19:33
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.12.2013, 19:33
Помогаю со студенческими работами здесь

Оптимизация кода
Есть такая статья http://habrahabr.ru/post/165729/. Но в ней перечислена лишь малая часть возможных...

Оптимизация кода
Доброго времени суток. Прошу прощения, если буду ошибаться в терминах, но постараюсь правильно...

Оптимизация кода
Возможно ли заменить быдло-код проверки - пуста ли строка и появления картинки возле неё? ...

Оптимизация кода
Добрый вечер, господа! В данный момент я пишу тулзу для демонстрации алгоритмов оценки движения и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Что такое HCL Notes и как с ним работать
InfoMaster 10.01.2025
HCL Notes (ранее известный как IBM Notes и Lotus Notes) представляет собой комплексную платформу для совместной работы и обмена информацией в корпоративной среде. Это многофункциональное решение,. . .
Как работать с Git из Windows и Visual Studio
InfoMaster 10.01.2025
Работа с Git в Windows Работа с Git в операционной системе Windows может быть осуществлена с помощью различных инструментов, каждый из которых обладает своими уникальными возможностями и. . .
Аналог оператора switch case в Python
InfoMaster 10.01.2025
Оператор switch case используется в программировании для выбора одного из нескольких вариантов исполнения кода. Однако в языке Python этот оператор отсутствует. Понимание аналогов switch case в. . .
Отличия абстрактного класса от интерфейса
InfoMaster 10.01.2025
В современной разработке программного обеспечения существуют два основных механизма реализации абстракции: абстрактные классы и интерфейсы. Эти инструменты, хотя и схожи в своей основной цели -. . .
Как работать в Git
InfoMaster 10.01.2025
Git — это одна из наиболее популярных систем контроля версий, которая активно используется разработчиками по всему миру. Она позволяет эффективно управлять изменениями в коде, координировать работу. . .
Реализация передвижения персонажа в Unity3d на C#
InfoMaster 10.01.2025
Реализация передвижения персонажа в Unity3D начинается с правильной настройки проекта. Этот этап критически важен для создания отзывчивого и плавного управления. Рассмотрим основные шаги для создания. . .
Docker: руководство для начинающих
InfoMaster 10.01.2025
В современном мире разработки программного обеспечения контейнеризация стала неотъемлемой частью процесса создания и развертывания приложений. Docker, как ведущая платформа контейнеризации, произвела. . .
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
Что такое NullReferenceEx­­­ception и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru