Эффективный формат обмена данными, использующий только операторы fprintf() в стиле C?

Мне нужно перенести очень большой набор данных (от 1 до 10 миллионов записей, возможно, намного больше) с предметно-ориентированного языка (единственным механизмом вывода которого является C-стиль). fprintf заявление) на Python.

В настоящее время я использую DSL fprintf записывать записи в плоский файл. Плоский файл выглядит так:

x['a',1,2]=1.23456789012345e-01
x['a',1,3]=1.23456789012345e-01
x['a',1,4]=1.23456789012345e-01
y1=1.23456789012345e-01
y2=1.23456789012345e-01
z['a',1,2]=1.23456789012345e-01
z['a',1,3]=1.23456789012345e-01
z['a',1,4]=1.23456789012345e-01

Как видите, структура каждой записи очень проста (но представление числа с двойной точностью в виде строки из 20 символов совершенно неэффективно!):

<variable-length string> + "=" + <double-precision float>

В настоящее время я использую Python, чтобы прочитать каждую строку и разделить ее на "=".

Что я могу сделать, чтобы сделать представление более компактным, чтобы Python мог быстрее читать? Возможно ли какое-то двоичное кодирование с fprintf?

2 ответа

Решение

Э-э-э... Сколько раз в минуту вы читаете эти данные из Python?

Потому что в моей системе я мог прочитать такой файл с 20 миллионами записей (~400 МБ) всего за секунду.

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

>>> timeit("all(b.read(20) for x in xrange(0, 20000000,20)  ) ", "b=open('data.dat')", number=1)
0.2856929302215576
>>> c = open("data.dat").read()
>>> len(c)
380000172

Компактный двоичный формат для сериализации значений с плавающей запятой определяется в основных правилах кодирования (BER). Там их называют "реалами". Доступны реализации BER для Python, но их тоже не сложно написать. Также есть библиотеки для Си. Вы можете использовать этот формат (для этого он и был разработан) или вариант (CER, DER). Одной из таких реализаций Python является pyasn1.

Другие вопросы по тегам