powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Инкрементирование строки
25 сообщений из 105, страница 3 из 5
Инкрементирование строки
    #39377146
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tпри тестах на скорость попробовал поменять на числа, стало быстрее. Было бы это мелочью, я бы не заметил из-за погрешности измерений, тестил разбором большого файла

Это бред. I/O операции перекрывают даже самые конские вычислительные расходы. А чтобы увидеть разницу в том, в чём разницы совершенно точно (на уровне IL кода) быть не может ну никак вообще ни при каких обстоятельствах, надо обладать даром, которым обладают только свидетели Иеговы
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377170
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttВот из-за кучи мелких заблуждений, из-за недоверия к компилятору, который отлично умеет оптимизировать код, вырастают твои никому не нужные костыли.
Хотел тестом проверить и наткнулся на такую интересную хрень
тестФайл отсюда http://services.fms.gov.ru/info-service.htm?sid=2000
Код: 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.
		public static void TestDigit(String file) {
			Console.WriteLine(file);
			var fs = new FileStream(file, FileMode.Open);
			var a = new Byte[fs.Length];
			fs.Read(a, 0, a.Length);

			Int32 cnt = 0, size = a.Length;
			var sw = Stopwatch.StartNew();
			//for (Int32 i = 0; i < size; i++) {
			//	var b = a[i];
			//	if (b >= 48 && b <= 57) cnt++;
			//}
			//Console.WriteLine($"if(b >= 48 && b <= 57) {sw.ElapsedMilliseconds} мс.  cnt: {cnt}");
			//cnt = 0;
			//sw.Restart();
			for (Int32 i = 0; i < a.Length; i++) {
				var b = a[i];
				if(b >= 48 && b <= 57) cnt++;
			}
			Console.WriteLine($"if(b >= 48 && b <= 57) {sw.ElapsedMilliseconds} мс.  cnt: {cnt}");
			cnt = 0;
			sw.Restart();
			for(Int32 i = 0; i < a.Length; i++) {
				var b = a[i];
				if(b >= '0' && b <= '9') cnt++;
			}
			Console.WriteLine($"if(b >= '0' && b <= '9') {sw.ElapsedMilliseconds} мс.  cnt: {cnt}");
			cnt = 0;
			sw.Restart();
			for(Int32 i = 0; i < a.Length; i++) {
				var b = a[i];
				if(Char.IsDigit((Char)b)) cnt++;
			}
			Console.WriteLine($"if(Char.IsDigit((Char)b)) {sw.ElapsedMilliseconds} мс.  cnt: {cnt}");
		}


При запуске как в тесте результат такой
Код: c#
1.
2.
3.
if(b >= 48 && b <= 57) 1184 мс.  cnt: 965430428
if(b >= '0' && b <= '9') 1188 мс.  cnt: 965430428
if(Char.IsDigit((Char)b)) 1151 мс.  cnt: 965430428


Но если раскаментить кусок кода, то у меня так получается
Код: c#
1.
2.
3.
4.
if(b >= 48 && b <= 57) 579 мс.  cnt: 965430428
if(b >= 48 && b <= 57) 574 мс.  cnt: 965430428
if(b >= '0' && b <= '9') 573 мс.  cnt: 965430428
if(Char.IsDigit((Char)b)) 1829 мс.  cnt: 965430428


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

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

PS На счет IO не согласен. В моем случае DBF сначала распаковывается, в результате чего чтение может быть не с диска, а из кэша виндовса. Да и диск SSD с чтением 700 Мб/сек.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377173
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВ DBF юникода не бывает, там ASCII кодировки

UTF-8 как будем трактовать?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377174
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВ моем случае DBF сначала распаковывается,
куда распаковывается? в память или на диск?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377178
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Путние люди постфиксы юзают.

Плохие_Девочки.address
Плохие_Девочки(1).address
Плохие_Девочки(2).address

И никаких переполнений!
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377198
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TВ DBF юникода не бывает, там ASCII кодировки

UTF-8 как будем трактовать?
Структура DBF поищи в Табл.9 как трактовать.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377199
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TВ моем случае DBF сначала распаковывается,
куда распаковывается? в память или на диск?
диск
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377214
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2Путние люди постфиксы юзают.

Плохие_Девочки.address
Плохие_Девочки(1).address
Плохие_Девочки(2).address

И никаких переполнений!
ИМХУ Путние люди делают идентификаторы числовыми и подобные топики не возникают за ненадобностью.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377225
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TХотел тестом проверить и наткнулся на такую интересную хрень

Так ты файлик то возьми нормального размеру, что бы регистрах процессора не помещался)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377226
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВDima TХотел тестом проверить и наткнулся на такую интересную хрень

Так ты файлик то возьми нормального размеру, что бы регистрах процессора не помещался)
Там файлик 1 Гб+. Ссылку дал, можешь качнуть.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377233
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кто не заметил, повторю результаты моего очень примитивного замера 20057914
Код: c#
1.
2.
3.
if(b >= 48 && b <= 57) 1184 мс.  cnt: 965430428
if(b >= '0' && b <= '9') 1188 мс.  cnt: 965430428
if(Char.IsDigit((Char)b)) 1151 мс.  cnt: 965430428


Но если раскаментить кусок кода, то у меня так получается
Код: c#
1.
2.
3.
4.
if(b >= 48 && b <= 57) 579 мс.  cnt: 965430428
if(b >= 48 && b <= 57) 574 мс.  cnt: 965430428
if(b >= '0' && b <= '9') 573 мс.  cnt: 965430428
if(Char.IsDigit((Char)b)) 1829 мс.  cnt: 965430428


Разница времени работы одного и того же кода отличается в 2 (ДВА) раза!!! Трижды перекомпилировал и запускал. Кто-нибудь повторите замеры, пожалуйста. Я в шоке!
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377257
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Странно. Первый случай скорее всего как раз показывает именно просадки из-за операций в памяти, когда IsDigit быстрее чем, сравнение (так может быть только если разница чем-то нивелируется). А ты говорил что-то там про SSD. Сравнил блин элементарную операцию на процессоре и операцию чтения с диска, которая проходит через несколько слоёв системы (драйвера, операция с диском...). Это на порядки всегда будет медленнее, чем элементарные вычисления.

Надо три теста выполнять отдельно и нужен разогрев. Выполнять тесты последовательно в одной и той же программе -- значит получить заведомо неверные результаты.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377528
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSD и IO тут ни при чем, в тесте сначала файл читается в массив, дальше циклы по массиву
Код: c#
1.
2.
3.
			var fs = new FileStream(file, FileMode.Open);
			var a = new Byte[fs.Length];
			fs.Read(a, 0, a.Length);


Поизучал IL-код циклов обоих EXE, он абсолютно одинаковый
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  IL_0084:  ldloc.0
  IL_0085:  ldloc.s    V_6
  IL_0087:  ldelem.u1
  IL_0088:  stloc.s    V_7
  IL_008a:  ldloc.s    V_7
  IL_008c:  ldc.i4.s   48
  IL_008e:  blt.s      IL_009a
  IL_0090:  ldloc.s    V_7
  IL_0092:  ldc.i4.s   57
  IL_0094:  bgt.s      IL_009a
  IL_0096:  ldloc.1
  IL_0097:  ldc.i4.1
  IL_0098:  add
  IL_0099:  stloc.1
  IL_009a:  ldloc.s    V_6
  IL_009c:  ldc.i4.1
  IL_009d:  add
  IL_009e:  stloc.s    V_6
  IL_00a0:  ldloc.s    V_6
  IL_00a2:  ldloc.0
  IL_00a3:  ldlen
  IL_00a4:  conv.i4
  IL_00a5:  blt.s      IL_0084


Попутно подтвердилось 20057782 что if(b >= 48 && b <= 57) и if(b >= '0' && b <= '9') компилируется в одно и тоже.

Еще одно наблюдениеРешил поправить чтение из файла на это
Код: c#
1.
2.
3.
4.
5.
			Byte[] a;
			using (var fs = new FileStream(file, FileMode.Open)) {
				a = new Byte[fs.Length];
				fs.Read(a, 0, a.Length);
			}


Больше ничего не трогал. Менял код туда-обратно несколько раз. Результат стабильный.
Вот результат до правки
Код: c#
1.
2.
3.
if(b >= 48 && b <= 57) 1202 мс.  cnt: 965430428
if(b >= '0' && b <= '9') 1203 мс.  cnt: 965430428
if(Char.IsDigit((Char)b)) 1159 мс.  cnt: 965430428


вот после
Код: c#
1.
2.
3.
if(b >= 48 && b <= 57) 781 мс.  cnt: 965430428
if(b >= '0' && b <= '9') 740 мс.  cnt: 965430428
if(Char.IsDigit((Char)b)) 1435 мс.  cnt: 965430428


вот поменял два последних цикла местами
Код: c#
1.
2.
3.
if(b >= 48 && b <= 57) 775 мс.  cnt: 965430428
if(Char.IsDigit((Char)b)) 1247 мс.  cnt: 965430428
if(b >= '0' && b <= '9') 768 мс.  cnt: 965430428


IL-код циклов тот же самый. Я проверил.


Получается что изменения одной части кода меняют скорость другой части. Знать бы еще почему и как этим пользоваться.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377545
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЭто бред. I/O операции перекрывают даже самые конские вычислительные расходы.
Тут ты не совсем прав. I/O работает параллельно с процом. Если чтение с диска достаточно быстрое, то может опережать. Особенно при последовательном чтении.

Давай мой тест просчитаем: файл 1.1 Гб обрабатывается 600 мс (предварительно скопированный в память), т.е. скорость моей обработки 1,8 Гб/сек. Скорость чтения рядового SSD 450-500 Мб/сек, т.е. всего в 4 раза ниже .
В теле цикла у меня одинокий if(), замени его на что-то реальное и чтение с диска начнет опережать расчеты.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377628
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TSSD и IO тут ни при чем

Ошибаешься, почитай немного про работу с памятью на уровне ОС, а также про работу с памятью на уровне .NET, куда кладутся маленькие объекты и куда большие и чем это может быть чревато.

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


Dima T Получается что изменения одной части кода меняют скорость другой части. Знать бы еще почему и как этим пользоваться.

Оптимизации компилятора, кеширование. Пользоваться этим надо только тогда, когда ты выяснил участок кода, на котором обнаружилось ощутимое падение производительности, так называемый bottleneck, не раньше.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377631
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T всего в 4 раза ниже

В твоей обработке тоже есть отнюдь не вычислительные операции, операции чтения из памяти тоже могут быть довольно затратны. Можно ускорить всё действо, при чём многократно, если читать файл блоками, а не цельным куском и обрабатывать его асинхронно в несколько потоков.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377633
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

при чём понятие "в 4 раза" сильно растяжимое.

4 больше 1 в 4 раза, т.е. больше на 3.

40 больше 10 в те же 4 раза, но уже больше на 30.

4000000 больше 1000000 в 4 раза, но уже на 3 миллиона.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377659
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttDima T всего в 4 раза ниже

В твоей обработке тоже есть отнюдь не вычислительные операции, операции чтения из памяти тоже могут быть довольно затратны. Можно ускорить всё действо, при чём многократно, если читать файл блоками, а не цельным куском и обрабатывать его асинхронно в несколько потоков.
Далеко не все файлы можно обрабатывать в несколько потоков. DBF легко, TXT сложнее но можно, XML или JSON - нельзя.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377675
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TXML или JSON - нельзя

Ты серьёзно? Нельзя?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377677
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Нет смысла читать из файла в несколько потоков, есть смысл в несколько потоков запускать обработку прочитанных блоков, если операция обработки затратная. Уточню чтобы ты правильно меня понял.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377702
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttDima T,

Нет смысла читать из файла в несколько потоков, есть смысл в несколько потоков запускать обработку прочитанных блоков, если операция обработки затратная. Уточню чтобы ты правильно меня понял.
С этим согласен, но само чтение того же XML это заметно посложнее чем код в цикле моего теста.

Простой пример из реального рабочего кода. Разбор XML файла. Код читает через XmlReader() и пишет в Dictionary<String, List<DataRow>>. Т.е. никакого лишнего IO кроме чтения файла.
Внутри цикла код достаточно простой. Получение тэгов, атрибутов, заполнение DataRow, сохранение в Dictionary. Тут нечего соседним потокам раздавать. Разве что "сохранение в Dictionary" заменить на постановку в ConcurrentQueue, а в другом потоке оттуда в Dictionary

А теперь цифры: разбор файла в 48 Мб идет 2.1 сек., скорость 23 Мб/сек. И где тут затык в IO ?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377744
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TРазве что "сохранение в Dictionary" заменить на постановку в ConcurrentQueue, а в другом потоке оттуда в Dictionary
Затестил, просто закамментил все что можно вынести в другой поток (добавление в Dictionary, проверку корректности заполнения и т.п.). Итого 0.8 сек. или 59 Мб/сек. Лучше, но тоже не сказать что много.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377786
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TА теперь цифры: разбор файла в 48 Мб идет 2.1 сек., скорость 23 Мб/сек. И где тут затык в IO ?

Это очень низкая скорость, они нивелирует затраты на тот же IsDigit не просто полностью, а с лихвой.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377789
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЛучше, но тоже не сказать что много.

Сравни чтение 1Гб файла с обработкой и без (чисто чтение). Разница будет, но сравни время на чтение и разницу между обработкой и без. Разницу убрать легко по-блочным чтением, т.е. не всего файла сразу, а блоками. Скорость чтения ты никак не сократишь. А экономия на миллисекундах, когда чтение выполняется минуты, это бесполезное занятие.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377825
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttDima TА теперь цифры: разбор файла в 48 Мб идет 2.1 сек., скорость 23 Мб/сек. И где тут затык в IO ?

Это очень низкая скорость, они нивелирует затраты на тот же IsDigit не просто полностью, а с лихвой.

Это скорость обработки , разбора. Тут тюнинг всяких IsDigit() как раз повышает эту скорость.
hVosttDima TЛучше, но тоже не сказать что много.

Сравни чтение 1Гб файла с обработкой и без (чисто чтение). Разница будет, но сравни время на чтение и разницу между обработкой и без. Разницу убрать легко по-блочным чтением, т.е. не всего файла сразу, а блоками. Скорость чтения ты никак не сократишь. А экономия на миллисекундах, когда чтение выполняется минуты, это бесполезное занятие.
Так я же написал что убрал всю обработку. Только чтение оставил.
Код цикла такой
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
                var row = new DataRow();
                while (xml.Read()) {
                    if(find_item) {
                        if (xml.Name.Equals("group", StringComparison.Ordinal)) {
                            find_item = false;
                            row.value1 = xml.GetAttribute("value1");
                            row.value2 = xml.GetAttribute("value2");
                            ...
                            row.value9 = xml.GetAttribute("value9");
                    } else {
                        if (xml.Name.Equals("subdata", StringComparison.Ordinal)) {
                            row.value10 = xml.GetAttribute("value10");
				r = new DataRow(row); // копия для добавление в Dictionary
                            // тут убрано добавление в Dictionary
                        } else if (xml.Name.Equals("group", StringComparison.Ordinal) && xml.NodeType == XmlNodeType.EndElement) {
                            find_item = true;
                        }
                    }
                }


Это все что осталось. Что тут убрать? Напомню это работает 0.8 сек.

Теперь тестим чтение
Код: c#
1.
2.
3.
4.
5.
6.
7.
			var sw = Stopwatch.StartNew();
			Byte[] a;
			using (var fs = new FileStream(file, FileMode.Open)) {
				a = new Byte[fs.Length];
				fs.Read(a, 0, a.Length);
			}
			Console.WriteLine($"{file} - {sw.ElapsedMilliseconds} мс");



17 мс, это нормально, потому что он давно в кэше ОС целиком. Вот и получается что 0.8 сек. это время работы цикла разбора.
...
Рейтинг: 0 / 0
25 сообщений из 105, страница 3 из 5
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Инкрементирование строки
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]