Буферы протокола Google огромные в Python - PullRequest
14 голосов
/ 08 августа 2011

Я начал использовать буферную библиотеку протокола, но заметил, что она использует огромное количество памяти.pympler.asizeof показывает, что один из моих объектов составляет около 76k!По сути, он содержит несколько строк, несколько чисел и некоторые перечисления, а также некоторые необязательные списки из них.Если бы я писал то же самое, что и C-структура, я бы ожидал, что он будет меньше нескольких сотен байтов, и действительно, метод ByteSize возвращает 121 (размер сериализованной строки).

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

Редактировать

Вот пример, который я построил.Это pb-файл, похожий, но более простой, чем тот, который я использовал

    package pb;

message A {
    required double a       = 1;
}

message B {
    required double b       = 1;
}

message C {
    required double c       = 1;
    optional string s       = 2;
}

message D {
    required string d       = 1;
    optional string e       = 2;
    required A a            = 3;
    optional B b            = 4;
    repeated C c            = 5;
}

И здесь я использую его

>>> import pb_pb2
>>> a = pb_pb2.D()
>>> a.d = "a"
>>> a.e = "e"
>>> a.a.a = 1
>>> a.b.b = 2
>>> c = a.c.add()
>>> c.c = 5
>>> c.s = "s"
>>> import pympler.asizeof
>>> pympler.asizeof.asizeof(a)
21440
>>> a.ByteSize()
42

У меня версия 2.2.0 protobuf (aнемного староват на данный момент) и python 2.6.4.

Ответы [ 2 ]

5 голосов
/ 09 августа 2011

Экземпляры объектов имеют больший объем памяти в python, чем в скомпилированных языках.Например, следующий код, который создает очень простые классы, имитирующие ваши прото, отображает 1440:

class A:
  def __init__(self):
    self.a = 0.0

class B:
  def __init__(self):
    self.b = 0.0

class C:
  def __init__(self):
    self.c = 0.0
    self.s = ""

class D:
  def __init__(self):
    self.d = ""
    self.e = ""
    self.e_isset = 1
    self.a = A()
    self.b = B()
    self.b_isset = 1
    self.c = [C()]

d = D()
print asizeof(d)

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

Версия C ++, безусловно, не страдает от этого.

0 голосов
/ 01 мая 2017

Редактировать: Это, скорее всего, не ваша настоящая проблема здесь, но мы только что испытали сообщение Protoff 45 МБ, принимающее> 4 ГБ оперативной памяти при декодировании.Похоже, что это: https://github.com/google/protobuf/issues/156

, о котором было известно в protobuf 2.6, и исправление было добавлено только в главный марш 7 в этом году: https://github.com/google/protobuf/commit/f6d8c833845b90f61b95234cd090ec6e70058d06

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...