Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Парсинг бинарного массива / 12 сообщений из 12, страница 1 из 1
26.05.2019, 14:05
    #39818365
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
Я делаю парсинг бинарного массива. Он сосотоит из последовательных записей. Каждая запись 23 байта и начинается с 55.
Код: 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.
public string ParseRawByteData(byte[] data, int size, ProgressBar pr_bar)
        {
            int g_idx = 0, l_idx;
            byte[] temp = new byte[23];
            string msg = "";

            if (pr_bar != null)
                pr_bar.Maximum = size;

            while (g_idx < size)
            {
                //find the message start
                if (data[g_idx] == 0x55)
                {
                    if ((g_idx + 23) > size)
                        break;

                    //copy the message to the temp buffer
                    for (l_idx = 0; l_idx < 23; l_idx++)
                    {
                        temp[l_idx] = data[g_idx + l_idx];
                    }

                    //parse the temp buffer
                    msg += ParseSingleMessage(temp);

                    //jump to the next message
                    g_idx += 23;
                }
                else
                    g_idx++;

                if (pr_bar != null)
                    pr_bar.Value = g_idx;

                Application.DoEvents();
            }

            return msg;
        }


        private string ParseSingleMessage(byte[] data)
        {
            string str = "";

            UInt32 crc;

            //message ID
            switch (data[1])
            {
                case 0x04: str += "MSG#4"; break;
                case 0x05: str += "MSG#5"; break;
                case 0x0A: str += "MSG#10"; break;
                case 0x0F: str += "MSG#15"; break;
                case 0x10: str += "MSG#16"; break;
                default: str += "Unknown message"; break;
            }

            crc = CRC(data, 21);

            if ((data[21] != (crc & 0xFF)) || (data[22] != (crc >> 8)))
            {
                str += "  Bad CRC";
            }

            str += "\r";

            return str;
        }


        private UInt32 CRC(byte[] data, int size)
        {
            UInt32 u32CRC_Value = 0xFFFF;
            UInt32 u32Byte_Index, u32Tmp1, u32Tmp2;
            byte b;

            for (u32Byte_Index = 0; u32Byte_Index < size; u32Byte_Index++)
            {
                u32Tmp1 = (u32CRC_Value << 8) & 0xFF00;
                u32Tmp2 = (u32CRC_Value >> 8) & 0x00FF;
                b = data[u32Byte_Index];
                u32Tmp2 ^= (UInt16)data[u32Byte_Index];
                u32CRC_Value = (u32Tmp1) ^ (UTL_CRC_au32CRC16_Table[u32Tmp2]);
            }

            return u32CRC_Value;
        }


Все парситься но страшно медленно. я уже смотрел как соптимизировать и что выкинуть - ничего не вижу.
...
Рейтинг: 0 / 0
26.05.2019, 14:22
    #39818369
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
уберите конкатенацию строк
msg += ParseSingleMessage(temp);
switch (data[1])
{
case 0x04: str += "MSG#4"; break;
case 0x05: str += "MSG#5"; break;
case 0x0A: str += "MSG#10"; break;
case 0x0F: str += "MSG#15"; break;
case 0x10: str += "MSG#16"; break;
default: str += "Unknown message"; break;
}

Используйте StringBuilder или TextWriter
...
Рейтинг: 0 / 0
26.05.2019, 14:27
    #39818371
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
Roman Mejtesуберите конкатенацию строк
msg += ParseSingleMessage(temp);
switch (data[1])
{
case 0x04: str += "MSG#4"; break;
case 0x05: str += "MSG#5"; break;
case 0x0A: str += "MSG#10"; break;
case 0x0F: str += "MSG#15"; break;
case 0x10: str += "MSG#16"; break;
default: str += "Unknown message"; break;
}

Используйте StringBuilder или TextWriter
я в конце хочу выдать результат на текстовый компонент. если я уберу msg += ParseSingleMessage(temp); что же я выдам?
...
Рейтинг: 0 / 0
26.05.2019, 14:29
    #39818373
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
jenya7,

Код: c#
1.
2.
3.
var sb = new StringBuilder();
sb.AppendLine(ParseSingleMessage(temp));
msg = sb.ToString();


или
Код: c#
1.
2.
3.
var tw = new TextWriter();
tw.WriteLine(ParseSingleMessage(temp));
msg = tw.ToString();
...
Рейтинг: 0 / 0
26.05.2019, 14:47
    #39818376
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
Roman Mejtesjenya7,

Код: c#
1.
2.
3.
var sb = new StringBuilder();
sb.AppendLine(ParseSingleMessage(temp));
msg = sb.ToString();


или
Код: c#
1.
2.
3.
var tw = new TextWriter();
tw.WriteLine(ParseSingleMessage(temp));
msg = tw.ToString();


фига се! реально шустро стал работать. спасибо.
...
Рейтинг: 0 / 0
26.05.2019, 16:04
    #39818399
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
Ты опять логику с UI перемешиваешь? Какого лешего у тебя там ProgressBar затесался? А за такой кошмар с magic numbers наследники твоего кода тебя так вообще проклянут до седьмого колена.
...
Рейтинг: 0 / 0
26.05.2019, 17:07
    #39818412
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
fkthatТы опять логику с UI перемешиваешь? Какого лешего у тебя там ProgressBar затесался? А за такой кошмар с magic numbers наследники твоего кода тебя так вообще проклянут до седьмого колена.
а что без прогрес бара сидеть и тупить в экран на 100 000 записей?
...
Рейтинг: 0 / 0
26.05.2019, 17:34
    #39818418
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
jenya7а что без прогрес бара сидеть и тупить в экран на 100 000 записей?
А что, другого способа передавать на UI состояние процесса, кроме как напрямую в прогрессбар писать не существует?

Хинт:
Код: c#
1.
public string ParseRawByteData(byte[] data, int size, Action<int> progressCallback)
...
Рейтинг: 0 / 0
26.05.2019, 23:10
    #39818518
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
jenya7
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
//copy the message to the temp buffer
                    for (l_idx = 0; l_idx < 23; l_idx++)
                    {
                        temp[l_idx] = data[g_idx + l_idx];
                    }

                    //parse the temp buffer
                    msg += ParseSingleMessage(temp);


1. можно еще не копировать, а передавать массив и начало (позицию) найденной записи
2. зачем каждый раз перепроверять на равенство 55? у вас же последовательные записи. или между ними может быть мусор?
3. зачем делать DoEvent на каждую найденную запись? помимо того, что это делать вообще не нужно, достаточно обеспечить максимум 10 раз в секунду, и то слишком часто. где то я встречал упоминание, что все равно более 60 раз в секунду невозможно обновлять форму
...
Рейтинг: 0 / 0
27.05.2019, 08:48
    #39818590
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
Arm79jenya7
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
//copy the message to the temp buffer
                    for (l_idx = 0; l_idx < 23; l_idx++)
                    {
                        temp[l_idx] = data[g_idx + l_idx];
                    }

                    //parse the temp buffer
                    msg += ParseSingleMessage(temp);


1. можно еще не копировать, а передавать массив и начало (позицию) найденной записи
2. зачем каждый раз перепроверять на равенство 55? у вас же последовательные записи. или между ними может быть мусор?
3. зачем делать DoEvent на каждую найденную запись? помимо того, что это делать вообще не нужно, достаточно обеспечить максимум 10 раз в секунду, и то слишком часто. где то я встречал упоминание, что все равно более 60 раз в секунду невозможно обновлять форму
1. Да. Тут я ступил.
2. Если есть битая запись или несколько битых записей я найду следущую.
3. Без DoEvent прогрес бар не двигается и весь ГУИ тоже. Можно конечно проредить вызов DoEvent.
...
Рейтинг: 0 / 0
27.05.2019, 09:23
    #39818597
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
jenya7Без DoEvent прогрес бар не двигается и весь ГУИ тоже
Тяжелый случай. Уж хоть какой-нить BackgroundWorker прикрутили бы, что ли...
...
Рейтинг: 0 / 0
27.05.2019, 09:35
    #39818604
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг бинарного массива
Сон Веры Павловны,
Только для прогрессбара оверхед).
Наверняка какая то утилита, где этот метод единственная работа.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Парсинг бинарного массива / 12 сообщений из 12, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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