Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Парсинг бинарного массива  [new]
jenya7
Member

Откуда:
Сообщений: 1140
Я делаю парсинг бинарного массива. Он сосотоит из последовательных записей. Каждая запись 23 байта и начинается с 55.
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;
        }

Все парситься но страшно медленно. я уже смотрел как соптимизировать и что выкинуть - ничего не вижу.
26 май 19, 14:05    [21894100]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3350
уберите конкатенацию строк
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
26 май 19, 14:22    [21894109]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
jenya7
Member

Откуда:
Сообщений: 1140
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); что же я выдам?
26 май 19, 14:27    [21894111]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3350
jenya7,

var sb = new StringBuilder();
sb.AppendLine(ParseSingleMessage(temp));
msg = sb.ToString();

или
var tw = new TextWriter();
tw.WriteLine(ParseSingleMessage(temp));
msg = tw.ToString();
26 май 19, 14:29    [21894114]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
jenya7
Member

Откуда:
Сообщений: 1140
Roman Mejtes
jenya7,

var sb = new StringBuilder();
sb.AppendLine(ParseSingleMessage(temp));
msg = sb.ToString();

или
var tw = new TextWriter();
tw.WriteLine(ParseSingleMessage(temp));
msg = tw.ToString();

фига се! реально шустро стал работать. спасибо.
26 май 19, 14:47    [21894119]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
fkthat
Member

Откуда:
Сообщений: 1143
Ты опять логику с UI перемешиваешь? Какого лешего у тебя там ProgressBar затесался? А за такой кошмар с magic numbers наследники твоего кода тебя так вообще проклянут до седьмого колена.
26 май 19, 16:04    [21894153]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
jenya7
Member

Откуда:
Сообщений: 1140
fkthat
Ты опять логику с UI перемешиваешь? Какого лешего у тебя там ProgressBar затесался? А за такой кошмар с magic numbers наследники твоего кода тебя так вообще проклянут до седьмого колена.

а что без прогрес бара сидеть и тупить в экран на 100 000 записей?
26 май 19, 17:07    [21894182]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
fkthat
Member

Откуда:
Сообщений: 1143
jenya7
а что без прогрес бара сидеть и тупить в экран на 100 000 записей?

А что, другого способа передавать на UI состояние процесса, кроме как напрямую в прогрессбар писать не существует?

Хинт:
public string ParseRawByteData(byte[] data, int size, Action<int> progressCallback)
26 май 19, 17:34    [21894190]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
Arm79
Member

Откуда: МО, Раменское
Сообщений: 3663
jenya7
//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 раз в секунду невозможно обновлять форму
26 май 19, 23:10    [21894309]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
jenya7
Member

Откуда:
Сообщений: 1140
Arm79
jenya7
//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.
27 май 19, 08:48    [21894402]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4820
jenya7
Без DoEvent прогрес бар не двигается и весь ГУИ тоже

Тяжелый случай. Уж хоть какой-нить BackgroundWorker прикрутили бы, что ли...
27 май 19, 09:23    [21894420]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг бинарного массива  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38643
Сон Веры Павловны,
Только для прогрессбара оверхед).
Наверняка какая то утилита, где этот метод единственная работа.
27 май 19, 09:35    [21894430]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить