powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Инкрементирование строки
105 сообщений из 105, показаны все 5 страниц
Инкрементирование строки
    #39376290
Slant-shadow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет. Можете помочь написать метод Инкриминирующий строку, принимающую в качестве аргумента в виде массива типа char. Пример результата:
00000007 - 00000008
SVA00001 - SVA00002
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376292
Фотография Нахлобуч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Slant-shadow,

Самостоятельные попытки были?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376294
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Slant-shadowИнкриминирующий
кто что кому инкриминирует?
прокурор дело шьёт?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376304
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Slant-shadowМожете помочь написать метод Инкриминирующий строку

Давай свою строку и в чём там её надо обвинить
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376349
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Придумай и словами алгоритм проговори и сразу поймешь как решать. Элементарная задача.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376364
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилSlant-shadowИнкриминирующий
кто что кому инкриминирует?
прокурор дело шьёт?
Методу инкриминируется строка. Т.е. метод криминальную строку принял и не сообщил куда следует. Что непонятного? Пакет Яровой в действии
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376481
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

не понял, что хочет автор.

если нужно инкрементировать char cимвол строки, то нужно знать 3 вещи:
а) строка это массив символов (char[])
б) 1 символ занимает 2 байта
в) Для получения кода символа можно использовать Convert.ToInt16(char), для получения символа из кода Convert.ToChar(short)


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

Дерзайте, передавайте привед преподавателю )
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376504
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesесли нужно инкрементировать char cимвол строки, то нужно знать 3 вещи:
а) строка это массив символов (char[])
б) 1 символ занимает 2 байта
в) Для получения кода символа можно использовать Convert.ToInt16(char), для получения символа из кода Convert.ToChar(short)

Достаточно знать первое и что char можно использовать как числовой тип
Код: c#
1.
2.
3.
4.
char c = '5';
c++;
if(c >= '0' && c <= '9') 
...
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376509
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Охренеть, вот это сила хрустального шара, так вы поняли чего хочет ТС?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376510
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как я понял есть некий идентификатор в виде строки с "числом" на конце, формат "ССССЦЦЦЦ", где С какие-то символы, Ц - цифры.
Надо сгенерить следующий такого же формата, сделав +1 к числу ЦЦЦЦ.
Например из "SVA00009" получить "SVA00010" и т.д.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376593
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

хм...

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
        public static string StrInc([NotNull] string s)
        {
            if (s == null) throw new ArgumentNullException(nameof(s));
            var m = Regex.Match(s, @"(?<prefix>[A-Za-z]+)?(?<number>\d+)", RegexOptions.Compiled);
            if (m.Success)
            {
                var prefixGroup = m.Groups["prefix"];
                var prefix = prefixGroup.Success ? prefixGroup.Value : string.Empty;
                var number = m.Groups["number"].Value;
                var n = long.Parse(number);
                return prefix + (++n).ToString().PadLeft(number.Length, '0');
            }
            throw new ArgumentException("Wrong input string!", nameof(s));
        }
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376619
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt, у тебя LINQ-зависимость

Тут одного цикла достаточно. И букав меньше будет.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public static string StrInc([NotNull] string s)
{
for(int i = s.Lenght - 1; i >= 0; i--) {
  if(s[i] >= '0' && s[i] < '9') {
     s[i]++;
     break;
  } else if(s[i] == '9') {
     s[i] = '0';
  } else {
      throw new ArgumentException("Wrong input string!", nameof(s));
  }
  return s;
}
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376626
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima ThVostt, у тебя LINQ-зависимость

Тут одного цикла достаточно. И букав меньше будет.

Твой код не рабочий, это видно не вооружённым глазом, даже без компилятора :)

А также читабельность и сопровождение на крайне низком уровне.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376633
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttТвой код не рабочий, это видно не вооружённым глазом, даже без компилятора :)
Я его сразу сюда писал. Не запускал. Скобку } пропустил перед return.

hVosttА также читабельность и сопровождение на крайне низком уровне.
Обычный алгоритмический код. Если я его по памяти написал, то прочитать тоже не сложно будет.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376634
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Slant-shadow,
Собеседование в Акуматике?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376645
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt, затести
Код: c#
1.
StrInc("11111111111111111111111111111111111111111")


:)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376660
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЯ его сразу сюда писал. Не запускал. Скобку } пропустил перед return.

Нет, твоя ошибка гораздо грубее и хуже. Тут не важно где ты писал и запускал или нет :)
Ошибка такая, что знающий человек её не допустит, даже если будет писать слюнявым пальцем на туалетной бумаге.




Dima TОбычный алгоритмический код.

Мой алгоритм:

1. Разбить строку на части: префикс и число.
2. Извлечь из числовой части, значимое число и длину.
3. Увеличить число на 1.
4. Перевести число в строку, добив нулями до изначальной длины.
5. Составить строку из префикса и новой числовой части.

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

Ошибка парсинга будет. Если надо работать с очень большими числами, я возьму BigInteger =)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376696
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima ThVosttТвой код не рабочий, это видно не вооружённым глазом, даже без компилятора :)
Я его сразу сюда писал. Не запускал. Скобку } пропустил перед return.

Нельзя просто так взять и инкриментировать чар в строке
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376703
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну и a9999 не прожует.

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

Я его сразу сюда писал. Не запускал. Скобку } пропустил перед return.

Нельзя просто так взять и инкриментировать чар в строке
1. Можно, но не буду учить плохому.
2. Slant-shadow принимающую в качестве аргумента в виде массива типа char.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376716
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttDima TЯ его сразу сюда писал. Не запускал. Скобку } пропустил перед return.

Нет, твоя ошибка гораздо грубее и хуже. Тут не важно где ты писал и запускал или нет :)
Ошибка такая, что знающий человек её не допустит, даже если будет писать слюнявым пальцем на туалетной бумаге.


Заинтриговал, договаривай, а то может ты просто сам запутался в моем примере, есть повод так думать
hVosttчитабельность и сопровождение на крайне низком уровне.

hVosttВот это алгоритм, его обычными словами можно описать и поймёт даже обезьяна.
А у тебя какие-то непонятные извращения с циклами и операциями с кодами символов.
Мой еще проще: сложение столбиком проходил в школе? Это оно и есть, +1 столбиком. Подробный алгоритм в учебнике по математике за 2 класс :)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376717
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
В акуматике еще в условии запрет на использование регэкспов.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376721
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ принимающую в качестве аргумента в виде массива типа char.

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

Строки в .NET не изменяемые, ты не можешь работать со строкой, как с массивом, а ты работаешь. Наигрубейшая ошибка надо сказать.

Даже если предположить, что строки стали работать как массивы, твой "алгоритм" вообще какую-то ерунду делает, не относящуюся к задаче ТС. Не решает задачу короче.

Я думаю на самом деле ты хотел изобразить что-то типа этого:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        public static string StrInc2([NotNull] string s)
        {
            if (string.IsNullOrEmpty(s)) throw new ArgumentException("Wrong string.", nameof(s));
            var b = new char[s.Length];
            var i = s.Length;
            while (--i >= 0 && char.IsDigit(s[i]))
            {
                var d = s[i] + 1;
                if (d > '9')
                {
                    b[i] = '0';
                }
                else
                {
                    b[i] = (char)d;
                    break;
                }
            }
            while (--i >= 0) b[i] = s[i];
            return new string(b);
        }
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376724
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВhVostt,
В акуматике еще в условии запрет на использование регэкспов.

Решение без регекспов выше привёл.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376726
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМой еще проще: сложение столбиком проходил в школе? Это оно и есть, +1 столбиком. Подробный алгоритм в учебнике по математике за 2 класс :)

И ты запутался в задачке для 2-го класса... Эх ты :)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376736
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pallarisну и a9999 не прожует.

Вариант Хвоста надежнее
Это зависит от ТЗ, к сожалению ТС этот момент не озвучил. Поэтому каждый может обрабатывать пограничные состояния по своему усмотрению.

Я считаю что a9999 должно вызвать исключение, т.к. это переполнение.
Все подобные кодировки, что мне попадались, всегда имели фиксированную ширину, поэтому добавление лишнего символа я считаю неправильным. Если правильно добавлять символ, то в моем коде просто заменить throw на вставку '1'.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376737
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Строки в .NET не изменяемые, ты не можешь работать со строкой, как с массивом, а ты работаешь. Наигрубейшая ошибка надо сказать.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
  unsafe static void M1()
        {
            string s = "hVostt";
            fixed(char* ch = s)
            {
                ch[0] = 'H';
            }
            Console.WriteLine(s);
        }
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376742
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVosttDima TЗаинтриговал, договаривай, а то может ты просто сам запутался в моем примере, есть повод так думать

Строки в .NET не изменяемые, ты не можешь работать со строкой, как с массивом, а ты работаешь. Наигрубейшая ошибка надо сказать.

Даже если предположить, что строки стали работать как массивы, твой "алгоритм" вообще какую-то ерунду делает, не относящуюся к задаче ТС. Не решает задачу короче.

Я думаю на самом деле ты хотел изобразить что-то типа этого:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        public static string StrInc2([NotNull] string s)
        {
            if (string.IsNullOrEmpty(s)) throw new ArgumentException("Wrong string.", nameof(s));
            var b = new char[s.Length];
            var i = s.Length;
            while (--i >= 0 && char.IsDigit(s[i]))
            {
                var d = s[i] + 1;
                if (d > '9')
                {
                    b[i] = '0';
                }
                else
                {
                    b[i] = (char)d;
                    break;
                }
            }
            while (--i >= 0) b[i] = s[i];
            return new string(b);
        }



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

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

Перенос единицы по сути -- продолжение цикла. Если нет переноса, то break.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376748
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ,

Хотя такие вещи возможны, например, при работе с алгоритмами шифрования и интеропом, но это исключение.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376763
Syrex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ColtСорри, может туплю, но где увеличивается цифра вижу, а вот случай, когда увеличенная цифра становиться больше 9 вижу только превращение ее в 0, но переноса единицы в следующий разряд не вижу.

А может должно быть так:
SCA009 -> SCA0010 ?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376765
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самое крутое, что скорее всего ТС больше здесь не появится :)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376770
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЯ думаю на самом деле ты хотел изобразить что-то типа этого
Я типа этого и изобразил, только с исключением при переполнении.

Как я уже понял надо было не тупо копировать строчку с исключением из твоего кода, а оформить понятнее. С исключением там косяк небольшой, на строке без букв его не будет, например "999"

Чуть поправил выдачу исключений, можешь потестить, этот запускается
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
        public static string StrInc(string v) {
			char[] s = v.ToArray();
			int i = s.Length - 1;
			for(; i >= 0; i--) {
				if(s[i] >= '0' && s[i] < '9') {
					s[i]++;
					break;
				} else if(s[i] == '9') {
					s[i] = '0';
				} else {
					throw new OverflowException();
				}
			}
			if(i < 0) throw new OverflowException();
			return new string(s);
		}
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376787
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttСтроки в .NET не изменяемые, ты не можешь работать со строкой, как с массивом, а ты работаешь.
В С/С++ меняются, тут нет, напутал немного.
hVosttНаигрубейшая ошибка надо сказать.
ХЗ что тут такого страшного, оно не компилируется. При всем желании не накосячишь. Суть была понятна, а это ляп кому надо сам поправит.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376823
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЯ считаю что a9999 должно вызвать исключение,
поддерживаю
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376841
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЧуть поправил выдачу исключений, можешь потестить, этот запускается

У тебя префиксы не поддерживаются, а у ТС есть примеры с префиксами.
Для поддержки последний OverflowException надо убрать.

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

Вот это:

if(s[i] >= '0' && s[i] < '9')
} else if(s[i] == '9') {

Это жесть! Надо внимательно вчитываться во все условия, чтобы 100% убедиться, что обрабатываются только цифры. В моём решении в цикл вход натурально возможен только если char.IsDecimal(s[i]) -- никаких двусмысленностей, 100% только числа внутри, это очевидно сразу при первом взгляде.

Я настоятельно не рекомендую писать код, который трудно читать. Иногда достаточно совсем небольших усилий, чтобы код стал понятным и прозрачным. Сложные вычурные условия вообще редко когда дают профит в производительности, скорее даже почти никогда не дают.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376878
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttУ тебя префиксы не поддерживаются, а у ТС есть примеры с префиксами.
Для поддержки последний OverflowException надо убрать.
Затести, я же написал что код запускается.
Код: c#
1.
2.
3.
4.
5.
			Console.WriteLine(StrInc("01"));
			Console.WriteLine(StrInc("09"));
			Console.WriteLine(StrInc("a01"));
			Console.WriteLine(StrInc("a09"));
			Console.WriteLine(StrInc("a99"));


Результат
Код: plaintext
1.
2.
3.
4.
5.
02
10
a02
a10

Необработанное исключение: System.OverflowException

hVosttНадо внимательно вчитываться во все условия, чтобы 100% убедиться, что обрабатываются только цифры. В моём решении в цикл вход натурально возможен только если char.IsDecimal(s[i]) -- никаких двусмысленностей, 100% только числа внутри, это очевидно сразу при первом взгляде.
Туда вообще смотреть не надо, надо просто описание к функции написать.
hVosttСложные вычурные условия вообще редко когда дают профит в производительности, скорее даже почти никогда не дают.
ХЗ что тяжелее: две элементарных проверки значения или вызов функции. Обычно второе.
Потом пройдись пошагово отладчиком по своему и моему коду и просто посчитай сколько действий у тебя и у меня.

Правда тут в первую очередь надо избавляться от перегонки из строки в массив и обратно, а потом уже прочий тюнинг.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376880
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сложение столбиком освоили?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376887
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПравда тут в первую очередь надо избавляться от перегонки из строки в массив и обратно
открой для себя StringBuilder
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376905
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TПравда тут в первую очередь надо избавляться от перегонки из строки в массив и обратно
открой для себя StringBuilder
Что он поменяет если на входе и выходе строка нужна?

У него тоже массив внутри.
StringBuilder.cs
Код: c#
1.
internal char[] m_ChunkChars;



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

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

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

Зачем? А если буквально через некоторое время задача усложнится, и надо будет прибавлять не 1, а 10? Или в зависимости от префикса? Твой код придётся полностью переписывать, в коде с регекспами я просто сделаю крошечное изменение: 1 заменю на 10! А если надо будет вот такие строки обрабатывать:

AK0001R-P
AK0002R-P

И при достижении 9999 должна меняться буква? Опять закатывать рукава и писать новый автомат?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377064
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttDima TХЗ что тяжелее: две элементарных проверки значения или вызов функции. Обычно второе.
Потом пройдись пошагово отладчиком по своему и моему коду и просто посчитай сколько действий у тебя и у меня.

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

Хотя может тебя просто прикалывают алгоритмические задачки и конечные автоматы, но в реале ты так не пишешь, а то я тут распинаюсь
Иногда пишу, но очень редко. Проекты разные бывают. Если простую функцию надо 100500 раз подряд вызвать, то есть смысл над ней поработать. Например парсинг файлов.

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

PS Кусочек заточенного реального кодаНаписал свою обертку для чтения DBF напрямую из файла.
Код: 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.
        Byte[] row; // Текущая запись
...
        // Получение значения поля в Int32 по названию
        public Int32 AsInt32(String field) {
            return AsInt32(GetFieldNum(field));
        }

        // Получение значения поля в Int32 по номеру
        public Int32 AsInt32(Int32 col_num) {
            var f = fields[col_num];
            Int32 end = f.offset + f.size;
            Int32 i = 0;
            Int32 pos = f.offset;
            while (pos < end && row[pos] == 32) pos++;
            while (pos < end) {
                Byte b = row[pos];
                if (b >= 48 && b <= 57) {
                    i = i * 10 + b - 48;
                } else {
                    break;
                }
                pos++;
            }
            return i;
        }


Как видишь тут еще жестче. Зато ни одного new.

эту строчку узнаешь?
Код: c#
1.
                if (b >= 48 && b <= 57) {


Тот самый Char.IsDigit(), именно так Byte проверяется быстрее даже чем
Код: c#
1.
                if (b >= '0' && b <= '9') {



Если был бы метод Int32.Parse(Byte[], Length, Оffset), то весь этот код можно было бы выкинуть.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377076
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Код: c#
1.
if (b >= 48 && b <= 57) {


Dima TТот самый Char.IsDigit(), именно так Byte проверяется быстрее даже чем

IsDigit работает очень и очень быстро, зря ты так

К слову, строка содержит символы, а не байты. Некоторый юникод, попавший в твою функцию может порвать её в клочья, а IsDigit легко выдержит удар.

Разницы по скорости между

b >= 48 && b <= 57

и

c >= '0' && c <= '9'

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

В DBF юникода не бывает, там ASCII кодировки. Тип numeric хранится как число записанное строкой.

Как понимаю при сравнении byte и char сначала идет неявное приведение типов к общему знаменателю, а при указании числом нет. Может еще что-то влияет. Когда писал изначально было if(b >= '0' && b < '9'), при тестах на скорость попробовал поменять на числа, стало быстрее. Было бы это мелочью, я бы не заметил из-за погрешности измерений, тестил разбором большого файла.
Char.IsDigit() не догадался затестить, но думаю что все-таки медленнее, т.к. "IsDigit легко выдержит удар" не может быть за бесплатно.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377137
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак понимаю при сравнении byte и char сначала идет неявное приведение типов к общему знаменателю, а при указании числом нет.

Занимательно, что ты даже не хочешь глянуть в IL код, чтобы убедиться, что это не так :)

Абсолютно параллельно с чем ты там сравниваешь byte или char, потому что они кладутся на стек как Int32 значения.

b <= '9'
b <= 57

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

Ты на чтении DBF теряешь времени больше, чем может отработать миллион вызовов IsDigit. Гораздо логичнее выглядит выражение "пустыню пылесосить", чем замена IsDigit на сравнения с числами. Но это уже у кого какие тараканы в голове
...
Рейтинг: 0 / 0
Инкрементирование строки
    #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
Инкрементирование строки
    #39377829
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
когда коту делать нечего - он яйца лижет
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377910
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttРазницу убрать легко по-блочным чтением, т.е. не всего файла сразу, а блоками. Скорость чтения ты никак не сократишь. А экономия на миллисекундах, когда чтение выполняется минуты, это бесполезное занятие.
Вобщем я к тому что разбор XML никак не сделать быстрее скорости чтения с SSD. Никакая многопоточность не поможет. Мой цикл 20061320 можно еще пооптимизировать, но схема:
Код: c#
1.
2.
3.
4.
5.
6.
7.
                            row = new MyRow();

                            row.value1 = xml.GetAttribute("value1");
                            row.value2 = xml.GetAttribute("value2");
                            ...
                            row.value9 = xml.GetAttribute("value9");
отправить row в очередь, для дальнейшей обработки в других потоках


никогда не обгонит чтение с SSD.

Хотя бы потому что каждый GetAttribute() помимо кода внутри еще и new string(), да и многопоточность не бесплатна, потокобезопасные классы (Concurrent...) заметно медленнее своих небезопасных аналогов. Обшую скорость постановки в очередь на обработку 100-200 Мб/сек наверно можно натюнинговать, но рядовой SSD дает чтение 450-500, на SATA2 чтение 200-220. Дисковый кэш виндовса 3-4 Гб/сек. Тут даже HDD с его 100 Мб/сек сложно обогнать.

ИМХУ ты диск с сеткой на 100 Мбит путаешь.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377956
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТут тюнинг всяких IsDigit() как раз повышает эту скорость.

Я не говорю, что подобный тюнинг не повышает скорость. Я говорю, что подобными оптимизациями можно пренебречь. Скажем так, если понадобится, я найду способ оптимизировать скорость и при этом IsDigit трогать не буду, потому что это самая-самая бестолковая оптимизация, которую только можно придумать. Оптимизацией это вообще нельзя никак назвать, экономия микросекунд, которую можно увидеть на миллиардах операций? Да тут кладезь того, что можно сделать в плане оптимизации, как я говорил, по-блочная многопоточная обработка, кеширование, оптимизация самого алгоритма. Ну никак не IsDigit, который не ощущается на фоне остальной обработки.

Ты когда первый раз в память гигабайт данных грузишь, что процессор у тебя в это время делает? Правильно, простаивает. А потом ты начинаешь заниматься "оптимизациями". Вот здесь и растут корни вселенского самообмана.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377957
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВобщем я к тому что разбор XML никак не сделать быстрее скорости чтения с SSD. Никакая многопоточность не поможет. Мой цикл 20061320 можно еще пооптимизировать, но схема:

Сам по себе разбор бесмысленный. Ты же что-то потом будешь делать с тем, что прочитал? Например, обрабатывать и куда-то записывать. Или вычислять. Или что-то ещё делать. Возможно твои действия потребуют нагрузки на память. И тут микрооптимизации это как зёрнышко для слона.

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

Это если тебе надо работать с разделяемыми ресурсами. Если ты найдёшь способ максимально изолировать данные друг от друга, или ещё лучше, работать с иммутабельными структурами, то пенальти за использование многопоточности будут оправданы многократным повышением общей производительности. Тут серебряной пули нет.

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

А вот тут ты ошибаешься. Файл может быть загружен как диска, так и по сети. Файл это абстракция ОС.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377994
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кому неймётся ускорять разбор xml - генерите код под конкретную схему
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39378102
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилКому неймётся ускорять разбор xml - генерите код под конкретную схему
[youtube=
YouTube Video
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39378447
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt, ты банальные слова написал, теорию. Ту нечему возразить. Разве что Закон Амдала не упомянул для полноты картины. Нет смысла спорить что грамотно спроектированный алгоритм с плохой реализацией гораздо проще оживить чем плохо спроектированный, но идеально закоденный. Но погоня за читабельностью может портить не только куски кода, но и алгоритм в целом. Грань тут тонкая.

По поводу IsDigit() соглашусь, можно ее использовать, копеечная экономия. Я на эти грабли наступил когда писал свой DBF парсер, просто заменил if(x >= '0' && x <= '9') на if(x >= 48 && x <= 57), попутно внеся косметические изменения в код и получил ускорение. Какие тут можно выводы сделать? Но как оказалось 20059862 код ускорили косметические изменения, как ни странно. Мне привычнее (x >= '0' && x <= '9') просто потому что IsDigit() нет в С/С++
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39378634
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМне привычнее (x >= '0' && x <= '9') просто потому что IsDigit() нет в С/С++
ужос какой.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39379566
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,
isdigit
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380415
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКакие тут можно выводы сделать?

В том, что если тебе надо реально ускорить парсинг, то есть намного более эффективные способы это сделать и получить ощутимое ускорение, а не на жалкие не значащие миллисекунды, которые к тому же плавают от запуска к запуску (зависит от кучи факторов).

Dima TМне привычнее (x >= '0' && x <= '9') просто потому что IsDigit() нет в С/С++

Учитывая, что C# работает с UTF-16, такой способ не является корректным. Что касается C/C++, если ты там работаешь с кодировками с переменным количеством байт (а это сегодня практически абсолютный стандарт во всём мире), то такое сравнение тоже не корректно.

Мы люди взрослые и сами решаем как нам привычнее отстреливать себе ноги, я же акцентирую на этом внимание, так как форум читает много людей и среди них много новичков.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380423
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttУчитывая, что C# работает с UTF-16, такой способ не является корректным. Что касается C/C++, если ты там работаешь с кодировками с переменным количеством байт (а это сегодня практически абсолютный стандарт во всём мире), то такое сравнение тоже не корректно.
не гони пургу - корректно и с UTF-16 и UTF-8
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380426
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилне гони пургу - корректно и с UTF-16 и UTF-8

Посмотри реализацию IsDigit и скажи нам, почему разработчики .NET не правы, а ты прав.
И тогда поговорим о пурге.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380434
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttесли ты там работаешь с кодировками с переменным количеством байт (а это сегодня практически абсолютный стандарт во всём мире), то такое сравнение тоже не корректно.
не путай тёплое с мягким - кодировка не влияет на классификацию кодовых точек(codepoint)

UTF-32 - всегда 4 байта на codepoint - как это влияет на классификацию?

теперь что касается собственно isDigit
в юникоде цифрами являются не только ASCII 0..9 ,
но и всяческие Bengali U+09E6 .. U+09EF и т д
isDigit для них вернёт true, но int.Parse их не поймёт

Для задачи топикстартера и им подобных - адекватным как раз является c>='0'' && c<='9' , а не isDigit
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380489
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

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

Изопропилно и всяческие Bengali U+09E6 .. U+09EF и т д
isDigit для них вернёт true, но int.Parse их не поймёт

Всё верно. Но надо учиться учитывать и другие культуры по возможности, даже если в конкретном случае это вроде как и не нужно.

ИзопропилДля задачи топикстартера и им подобных - адекватным как раз является c>='0'' && c<='9' , а не isDigit

Адекватным является либо IsDigit, либо своя функция IsArabicDigit, но ни как не c>='0'' && c<='9', я даже не понимаю в чём тут спор, код должен быть простым, понятным, односложным, самодокументированным. В указанном тобой утверждении можно сделать ошибку, которую очень легко не заметить. Привыкнешь писать такой код потом тяжело будет работать в адекватной команде, где за такое дают по шапке.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380491
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилUTF-32 - всегда 4 байта на codepoint - как это влияет на классификацию?

На самом деле UCS-4, из UTF в основном используются UTF-8 и UTF-16.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380505
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,

суррогатные пары UTF-16 (0xD800—0xDFFF) никак не влияют на проверку на ascii 0..9


UCS-4 и UTF-32 в 2017 году - одно и то же

hVosttНо надо учиться учитывать и другие культуры по возможности, даже если в конкретном случае это вроде как и не нужно.
именно поэтому isDigit и isNumber нужно использовать в полном сознании (проверка на попадание в категории Nd и No)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380513
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttIsArabicDigit
вот тут и накрылся медным тазом "самодокументированный" код

я, например, за именем этой фукции вижу проверку на диапазон U+06F0 .. U+06F9,
хотя могу и заподозрить индоарабские U+0660 .. U+0669
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380634
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилсуррогатные пары UTF-16 (0xD800—0xDFFF) никак не влияют на проверку на ascii 0..9


UCS-4 и UTF-32 в 2017 году - одно и то же

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

UTF-32 приравняли к UTC-4, чтобы не было путанницы.

Изопропилименно поэтому isDigit и isNumber нужно использовать в полном сознании (проверка на попадание в категории Nd и No)

Нужно, не спорю.


Изопропилот тут и накрылся медным тазом "самодокументированный" код

я, например, за именем этой фукции вижу проверку на диапазон U+06F0 .. U+06F9,
хотя могу и заподозрить индоарабские U+0660 .. U+0669

Ты уже лепишь отсебятину ))
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380676
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttИзопропилсуррогатные пары UTF-16 (0xD800—0xDFFF) никак не влияют на проверку на ascii 0..9


UCS-4 и UTF-32 в 2017 году - одно и то же

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

UTF-32 приравняли к UTC-4, чтобы не было путанницы.

херню несёшь, никакой путаницы нет
codepoint ни из каких слов не состоит.
"два слова" - суррогатные пары - исключительно особенность UTF-16 (d800..dfff)к чему ты их сюда приплёл?
многобайтовый последовательности UTF-8 - первый байт 11xxxxxx, последующие - 10xxxxxxx

отличия между UTF-32 и UCS-4 были в трактовке диапазона значений (изначально предполагалось, что будет задействован диапазон 0..7FFFFFFF
нынче это 0..10FFFF

UTF-32 - юникод консорциума, а UCS-4 - ISO10646 (ещё был померший UCS-2)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380771
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил"два слова" - суррогатные пары - исключительно особенность UTF-16 (d800..dfff)к чему ты их сюда приплёл?

Ты из какой планеты прилетел? .NET работает со строками в кодировке UTF-16. Представляешь? все исключительные особенности UTF-16 — это то, с чем приходится жить, разрабатывая под .NET

А при чём тут твои UTF-32/UCS-4 или UTF-8? Зачем вообще ты про них заговорил? К чему, для чего? В .NET используется UTF-16.


Изопропилмногобайтовый последовательности UTF-8 - первый байт 11xxxxxx, последующие - 10xxxxxxx

И чего? В .NET строках сидит UTF-16.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380781
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttВ .NET строках сидит UTF-16.
и что теперь? UTF-16 ещё в Java и Javascritpt

hVosttПроблема в том, что ты рассматриваешь символы как ASCII, когда работаешь с юникодом это не ASCII, так как символ может состоять из двух слов
я рассматриваю символы как кодовые точки юникода
кодовая точка представляется в UTF-16 суррогатной парой ("двумя словами") для плоскостей 1-16

где я что про ASCII сказал?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380829
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропиля рассматриваю символы как кодовые точки юникода
кодовая точка представляется в UTF-16 суррогатной парой ("двумя словами") для плоскостей 1-16

Вообще-то ты прав, в плоскость суррогатных пар не попадают значения '0'..'9'.
А я подумал про модифицирующие сѝмволы: 0̀1̀2̀3̀4̀6̀7̀8̀9̀...
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380842
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автора наверное давно отчислили, а тема всё перетерается :) из мухи слона уже раздули :)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380852
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesиз мухи слона уже раздули
юникод - тема большая и интересная, не меньше слона.

в частности - классификация символов и обработка их сочетаний

"цифр" в юникоде, как выясняется куда больше чем 10.
а 1 не digit, а number
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380866
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил"цифр" в юникоде, как выясняется куда больше чем 10.
а 1 не digit, а number

Ну не то, чтобы в юникоде, вообще, в жизни их больше, в математике, в типографике, в различных культурах.
А в юникод уже затолкали всё что только можно, даже эмодзи.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380877
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttА в юникод уже затолкали всё что только можно
ещё не всё, остались неохваченные аспекты

это всё ещё нужно корректно обрабатывать
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380905
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
https://www.microsoft.com/typography/developers/opentype/default.htm

короткий достаточно старый обзор Windows Glyph Processing
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39380967
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

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


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