Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 23.02.2016
Сообщений: 4
.NET 3.x

Разделение цикла for на маленькие методы - какой лучший вариант по производительности?

17.11.2017, 19:48. Показов 853. Ответов 7

Студворк — интернет-сервис помощи студентам
Что лучше с точки зрения быстродействия и производительности?

Цикл в одном месте, а дальше в каждый такт цикла вызывать все нужные методы:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for(int i = 0, i < array.Length, i++){
    MethodA (i);
    MethodB (i);
    MethodC (i);
}
 
void MethodA (int i) {
    //do something
}
 
void MethodB (int i) {
    //do something
}
 
void MethodC (int i) {
    //do something
}
Дублирование цикла в каждом методе:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void MethodA () {
    for(int i = 0, i < array.Length, i++){
        //do something
    }
}
void MethodB () {
    for(int i = 0, i < array.Length, i++){
        //do something
    }
}
void MethodC () {
    for(int i = 0, i < array.Length, i++){
        //do something
    }
}
Или последовательный вызов следующего метода из предыдущего, вместе с передачей переменной цикла:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void MethodA () {
    for(int i = 0, i < array.Length, i++){
        //do something
        MethodB (i);
    }
}
 
void MethodB (int i) {
    //do something
    MethodC (i);
}
 
void MethodC (int i) {
    //do something
}
Если это важно, код создается для Unity.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.11.2017, 19:48
Ответы с готовыми решениями:

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

Drawingvisual или Usercontrol: какой вариант будет реализовать правильней с точки зрения производительности
передомной стоит задача написать программу.чтобы было можно рисовать некоторые uml диаграммы(вариантов использования,диаграмма...

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

7
 Аватар для Skorp24
52 / 50 / 26
Регистрация: 15.06.2009
Сообщений: 390
18.11.2017, 12:37
Всё зависит от того, что там конкретно происходит в "do something". Вы можете просто выполнить каждый сценарий в цикле миллион раз и измерить время, за которое подобный цикл выполняется.

Если на месте "do something" будет, например, сложение "1+1", то первый способ будет показывать наибольшую производительность.
0
0 / 0 / 0
Регистрация: 23.02.2016
Сообщений: 4
18.11.2017, 21:10  [ТС]
Skorp24, а почему именно первый?
0
Администратор
Эксперт .NET
 Аватар для tezaurismosis
9673 / 4825 / 763
Регистрация: 17.04.2012
Сообщений: 9,664
Записей в блоге: 14
18.11.2017, 21:14
Первый способ быстрее второго, т.к. в нём только один цикл вместо трёх и проверка условия цикла будет выполнена array.Length - 1 раз, а не 3 * (array.Length - 1) раз (для второго метода). Третий метод в этом отношении схож с первым.
Имхо, большее значение здесь имеет стиль написания кода. Второй способ нарушает принцип DRY. Третий способ запутаннее всех из-за необходимости прослеживать при чтении цепь вызова методов.
Так что первый способ - лучший.
0
 Аватар для Skorp24
52 / 50 / 26
Регистрация: 15.06.2009
Сообщений: 390
18.11.2017, 22:35
Цитата Сообщение от tezaurismosis Посмотреть сообщение
Второй способ нарушает принцип DRY.
Тем, что в трёх методах одинаковое объявление цикла? Можно, конечно, создать метод, который предназначен для того, чтобы выполнять в цикле for произвольный код, но, по-моему, это лишнее. У штампования подпрограмм на любую строку кода, повторяющуюся больше одного раза, тоже есть недостатки. Сам оператор for (без выполняемого кода), я считаю, можно приравнивать к полноценной подпрограмме, которая принимает аргументы и что-то с ними делает.
0
Администратор
Эксперт .NET
 Аватар для tezaurismosis
9673 / 4825 / 763
Регистрация: 17.04.2012
Сообщений: 9,664
Записей в блоге: 14
18.11.2017, 22:46
Цитата Сообщение от Skorp24 Посмотреть сообщение
Тем, что в трёх методах одинаковое объявление цикла?
Если методы MethodA, B и C как-то по назначению связаны друг с другом, например, представляют из себя три стадии выполнения какого-то процесса, то код с одним циклом будет выглядеть яснее. Если они просто по счастливой случайности должны повториться одинаковое количество раз - тогда лучше три цикла внутри методов.
0
 Аватар для Skorp24
52 / 50 / 26
Регистрация: 15.06.2009
Сообщений: 390
18.11.2017, 23:14
tezaurismosis, ну, допустим, MethodA должен в условиях ограничения по времени считать в массив информацию из какого-нибудь источника. MethodB должен произвести с каждым элементом массива какую-нибудь затратную операцию, тем самым изменив его. MethodC должен вычислить какую-нибудь контрольную сумму на полученном в результате массиве. Вот и счастливая случайность.
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
19.11.2017, 02:00
Цитата Сообщение от tezaurismosis Посмотреть сообщение
Первый способ быстрее второго, т.к. в нём только один цикл вместо трёх
Зато в нём 3 * array.Length операторов вызова метода. В третьем варианте их на треть меньше. Отсюда и результат.
Кликните здесь для просмотра всего текста
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
class Diagnostics : IDisposable
{
    private string _title;
    private Stopwatch _timer;
    
    public Diagnostics(string title)
    {
        _title = title;
        _timer = Stopwatch.StartNew();
    }
    
    public void Dispose()
    {
        _timer.Stop();
        if (_title != null)
        {
            Console.Write(_title + ": ");
        }
        Console.WriteLine(_timer.Elapsed);
    }
}
 
class SingleFor
{
    private long _unused;
    
    public void Run(int count)
    {
        for (int i = 0; i < count; i++)
        {
            MethodA(i);
            MethodB(i);
            MethodC(i);
        }
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodA(int i)
    {
        _unused += i;
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodB(int i)
    {
        _unused += i;
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodC(int i)
    {
        _unused += i;
    }
}
 
class TrippleFor
{
    private long _unused;
    
    public void Run(int count)
    {
        MethodA(count);
        MethodB(count);
        MethodC(count);
    }
 
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodA(int count)
    {
        for (int i = 0; i < count; i++)
        {
            _unused += i;
        }
    }
 
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodB(int count)
    {
        for (int i = 0; i < count; i++)
        {
            _unused += i;
        }
    }
 
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodC(int count)
    {
        for (int i = 0; i < count; i++)
        {
            _unused += i;
        }
    }
}
 
class ChainCall
{
    private long _unused;
    
    public void Run(int count)
    {
        MethodA(count);
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodA(int count)
    {
        for (int i = 0; i < count; i++)
        {
            _unused += i;
            MethodB(i);
        }
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodB(int i)
    {
        _unused += i;
        MethodC(i);
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private void MethodC(int i)
    {
        _unused += i;
    }
}
 
void Main()
{
    int count = 100 * 1000 * 1000;
    
    var single = new SingleFor();
    var tripple = new TrippleFor();
    var chainCall = new ChainCall();
    
    // heat up
    single.Run(1);
    tripple.Run(1);
    chainCall.Run(1);
 
    Console.WriteLine($"Count = {count.ToString("N0", CultureInfo.CreateSpecificCulture("Ru-ru"))}");
    
    using (new Diagnostics("Single for"))
    {
        single.Run(count);
    }
 
    using (new Diagnostics("Tripple for"))
    {
        tripple.Run(count);
    }
    
    using (new Diagnostics("Chain call"))
    {
        chainCall.Run(count);
    }
}

Code
1
2
3
4
Count = 100 000 000
Single for: 00:00:00.9082599
Tripple for: 00:00:00.7999134
Chain call: 00:00:00.8471940
Вывод: без разницы какой вариант использовать, так как, в частности,
Цитата Сообщение от Skorp24 Посмотреть сообщение
MethodB должен произвести с каждым элементом массива какую-нибудь затратную операцию
откуда следует ничтожная относительная (процентная) разница в производительности.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.11.2017, 02:00
Помогаю со студенческими работами здесь

Лучший вариант записи в .txt
Кто нить замерял как лучше вносить данные в текстовый фаил На данный момент из списка закидываю в стринг а потом записываю в фаил если 5...

Цикл в цикле? Каков лучший вариант?
Господа, поделитесь опытом, пожалуйста, для общего блага среди начинающих. Как лучше ввсего организовать цикл в цикле для решения...

Лучший вариант размещения robots.txt
Использую на продакшене django+nginx+gunicorn. Как лучше отдавать robots.txt? Первый вариант: генерировать в Django urlpatterns =...

Лучший вариант локализации своего интерфейса
Есть задача изменять язык интерфейса программы. Сейчас делаю так: есть статический класс localizer, в котором содержатся публичные...

Лучший вариант для работы с Modbus
Здравствуйте. Внезапно у меня появилась задача: организовать передачу данных от приложения с помощью Modbus по tcp/ip. Начал гуглить,...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru