Страница 2 из 3

Re: Быстрое чтение разнотипных данных

Добавлено: 07 июн 2016, 09:31
Blackman
Не надо изобретать велосипед.)

TDMS File Format Internal Structure
http://www.ni.com/white-paper/5696/en/
VI-Based API for Writing TDMS Files
http://www.ni.com/white-paper/6471/en/
http://ftp.ni.com/pub/devzone/tut/gtdms_8.x.zip

Re: Быстрое чтение разнотипных данных

Добавлено: 07 июн 2016, 10:08
Borjomy_1
XAPOH писал(а):Вот только у него сверху надо указать тип, а с ним у меня и есть огромная проблемища.
Тут элементарно. Перед записью указывается ее тип. Сначала считывается тип, потом вызывается соответствующая структура, которая вычитывает данные соответственно типу.

Но лучше присмотреться к TDMS

Re: Быстрое чтение разнотипных данных

Добавлено: 07 июн 2016, 12:56
XAPOH
Перед записью указывается ее тип.
Writing TDMS Files
Боюсь что у меня проблема с чтением файлов, а не в записи. Мне предоставят файлы, а я должен построить графики
TDMS File Format
К сожалению я не могу выбирать формат подаваемых мне файлов. Может я чего то не понял, но вы мне предлагаете сначала сохранить в TDMS, чтобы потом пользоваться его инструментами и читать. Верно?

Я думаю должен пояснить, что пытаюсь открыть файлы в формате COMTRADE, стандарта 2013 года. Я знаю что :labview: имеет инструмент для их просмотра, входящий в Electrical Power чего то там, но я так и не смог им воспользоваться-он во первых отказался открывать, а во вторых-вроде он был платный. Я уже не помню.
Read_File6.jpg
Поэтому изучил стандарт COMTRADE 2013 и написал собственный просмотрщик аналоговых сигналов
Reader_Comtrade 06_06_2016.rar
Просмотрщик комтрейд на 2 аналоговых сигнала. Файлы для просмотра (TrT1.cdf и TrT1.dat) внутри архива
(77.94 КБ) 213 скачиваний
Файлы для просмотра (TrT1.cdf и TrT1.dat) внутри архива.

Когда я решил добавить туда считывание дискретных сигналов(по стандарту они упаковываются в переменные типа U16)-я столкнулся с проблемой, с которой и пришел на форум: как быстро считывать значения из бинарного файла, если там разные по длине переменные? Если хочешь использовать Read From Binary File-то нельзя указывать тип "массив", т.к. во первых сама функция чтения требует указания количества записей, а во вторых в массиве могут быть только переменные одного типа (и соответственно одинаковой длины).
Идеально подходит в качестве типа указывать кластер с нужной структурой (которую читаешь из *.cfg файла)-Read From Binary File его поддерживает, счетчиков в начале файла не нужно, но кластер с нужной структурой нельзя создавать динамически! Я могу руками открыть *.cfg файл, понять сколько переменных какой длины будет, и собрать кластер в качестве типа для Read From Binary File. Но я это делаю руками! Персонально под каждый файл! А значит я никому не могу дать свою программу, потому что ее под каждый файл надо переписывать! Кластеры нельзя динамически типизировать.

От отчаяния я сейчас доделываю следующее решение: читаю весь файл как массив U16, а потом в цикле начинаю объединять те ячейки массива, какие нужно в соответствии с информацией из *.cfg файла и создаю новые массивы U32, I32, I16 в зависимости от этого из исходного U16. Решение мне кажется уродливым, но это лучше чем ничего.
не красивое решение
не красивое решение
Может кто нибудь предложить способ лучше?
Тестовые файлы с 2 аналоговыми и 2 дискретными сигналами:
TrT2.rar
Тестовые файлы с 2 аналоговыми и 2 дискретными сигналами
(581 байт) 211 скачиваний

Re: Быстрое чтение разнотипных данных

Добавлено: 07 июн 2016, 18:51
dadreamer
XAPOH писал(а):Может кто нибудь предложить способ лучше?
XAPOH писал(а):Не, чтобы был кластер из 2 Unsigned Int32, а потом стал кластер из 2 Unsigned Int32, N Int32 и K Unsigned Int16. В рантайме. А K и N брались из текстового файла
Я бы так сделал (как впрочем я уже советовал вам):
2016-06-07_20-42-43.jpg
Read_Bin_File.png
2016-06-07_20-41-58.jpg
2016-06-07_20-41-58.jpg (30.16 КБ) 12247 просмотров
Бесполезно пытаться читать свои собственные форматы через Read From Binary File. Особенно массивы, строки и кластеры из них. :labview: ожидает свой формат представления данных: например, перед массивом обязательно должна стоять его длина (I32), перед строкой - так же. Если длины нет, то ни :labview: , ни какая-то другая среда просто не во состоянии понять, где заканчивается один массив и начинается другой элемент. Так что для экзотических форматов наподобие вашего лучшим решением будет получать весь поток байт из файла и интерпретировать его согласно текущему формату (полагаю, длины массивов N и K заранее известны, иначе ничего не выйдет).
З.Ы.: понятно, что комменты - штука очень личная, но всё же... Здесь же приличная аудитория сидит. :D

Re: Быстрое чтение разнотипных данных

Добавлено: 09 июн 2016, 22:51
XAPOH
Спасибо большое! С изменившимся ТЗ это решение подходит как нельзя лучше! :thank:

Re: Быстрое чтение разнотипных данных

Добавлено: 13 июл 2016, 16:19
XAPOH
dadreamer писал(а):Я бы так сделал (как впрочем я уже советовал вам):
Вложение 2016-06-07_20-42-43.jpg больше недоступно
Вложение Read_Bin_File.png больше недоступно
Вложение 2016-06-07_20-41-58.jpg больше недоступно
И снова я в этой теме. Сделал все как советовали, после того как немного изменился формат файла я полностью принял решение.
Медленый лв1.png
Во время тестов все работало замечательно! Пока в файле было порядка 50 записей. На обработку всех записей уходили миллисекунды.

Теперь программу стали испытывать на практике и в файле 300 000 записей и мои худшие опасения (из за чего я вообще и создавал эту тему) сбылись. Тормозит ужасающе. На обработку одной (!) записи (27 U32 и 1 U16) уходит больше 1 секунды. а записей там, повторюсь, около 300 000. У меня есть смутные подозрения что дело в передаче данных через шифт регистры (теперь там данных стало больше 30 мегабайт), но наверняка я не знаю.
Подскажите как быть, пожалуйста!
Прикладываю архив, форум файл в 2,8мб кушать отказывается: https://yadi.sk/d/fJYLkvWBtGB4W
Файл TrT2.cff-тестовый на 50 записей
Файл Trend_test_10_40.cff-реальный
Чтобы открыть нажимаем на белое поле под цифрой красной 1, выбираем файл, потом на кнопку под красной цифрой 2
Медленый лв2.png
Вдогонку вопрос, не могу вспомнить как сделать чтобы элементы на окне автоматически масштабировались под размеры окна?

Re: Быстрое чтение разнотипных данных

Добавлено: 13 июл 2016, 17:03
Borjomy_1
Каждая манипуляция со строками приводит к перераспределению памяти. А вы на КАЖДОМ разборе числа переписываете ВЕСЬ файл, который находится в памяти в виде строки. :cantbe:

Re: Быстрое чтение разнотипных данных

Добавлено: 13 июл 2016, 17:15
XAPOH
Ого, это прямо почти как у меня раньше было! Сейчас попробую

Re: Быстрое чтение разнотипных данных

Добавлено: 13 июл 2016, 18:32
dadreamer
XAPOH, раз у вас такие большие объёмы данных, то наверное следует читать файл по частям. Не знаю, может, вы уже пробовали это... Вот похожая тема: http://www.labviewportal.org/viewtopic. ... 817#p70817 Только там в начале файла присутствует заголовок, а дальше идут полезные данные. Обратите внимание, что чтение по частям не означает, что нужно прочесть файл за раз (хоть частями, хоть целиком). Это означает, что программа работает только с одной частью (порцией) данных в определённый момент времени.
XAPOH писал(а):Вдогонку вопрос, не могу вспомнить как сделать чтобы элементы на окне автоматически масштабировались под размеры окна?
File -> VI Properties -> Window Size -> галочка "Scale all objects on front panel as the window resizes"

Re: Быстрое чтение разнотипных данных

Добавлено: 13 июл 2016, 21:56
XAPOH
Borjomy_1 писал(а):Каждая манипуляция со строками приводит к перераспределению памяти. А вы на КАЖДОМ разборе числа переписываете ВЕСЬ файл, который находится в памяти в виде строки. :cantbe:
Сделал. Действительно, офигенно ускорилось, спасибо большое. Но у меня теперь вопрос: что делать с порядком байтов? как мне сделать little-endian и вообще как его поменять?

Re: Быстрое чтение разнотипных данных

Добавлено: 13 июл 2016, 21:58
XAPOH
dadreamer писал(а): File -> VI Properties -> Window Size -> галочка "Scale all objects on front panel as the window resizes"
спасибо, поставил :super:

Re: Быстрое чтение разнотипных данных

Добавлено: 13 июл 2016, 22:00
Borjomy_1
как мне сделать little-endian и вообще как его поменять?
Перед TypeCastом сделать реверс массива и после

Re: Быстрое чтение разнотипных данных

Добавлено: 14 июл 2016, 00:12
XAPOH
Borjomy_1 писал(а):
как мне сделать little-endian и вообще как его поменять?
Перед TypeCastом сделать реверс массива и после
с U32 помогло. сделал после Type Cast сделал Swype Bytes
а вот с U16 что то не получается. щас похимичу ещё.
а почему нужно перед Type Cast? от этого быстрее работать будет?

Re: Быстрое чтение разнотипных данных

Добавлено: 14 июл 2016, 08:47
Borjomy_1
Перед тайпкастом разворачивается порядок следования байт, но также разворачивается и порядок следования каналов. Реверс массива после преобразования восстанавливает справедливость.

Re: Быстрое чтение разнотипных данных

Добавлено: 14 июл 2016, 09:19
rbl
1. Если длина каждой записи известна заранее (информация о длине не записана в структуре посылки), то последовательный парсер нужно заменить на параллельный. Очень большой прирост производительности.
2. Если записи одной длины, то хранить данные в одномерном массиве, а не в двумерном. Если длина разная - использовать одномерный массив кластеров. Большой прирост.
3. Прочитать бинарный файл, целиком сконвертить в тот же u16 и парсить уже массив u16, а не строку. Позволит избежать работы со строкой, шифт регистром, дикого кол-ва преобразований и потенциально распараллелить. Дикий прирост.
4. По возможности не использовать Mixed Signal Graph, поскольку в него входит Digital Graph, который в 2015 версии конечно поправлен, но все равно довольно тормозная штука. Лучше работать с аналогом, а для отображения цифровых использовать аналоговые сигналы конечной амплитуды сдвинутые друг относительно друга. Прирост зависит от проекта и иногда весьма ощутимый.

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