2017-02-07 10 views
0

Я использую API, который обеспечивает 128 сигналов (и значений качества сигнала) в секунду в качестве dict в dict. Я хочу собрать их в окна из 1 (или более) секунд.Соберите дискретные рамки в объекте python с соответствующей и быстрой структурой данных

Мой родной подход состоял в том, чтобы использовать ту же структуру dict и добавить значения в списки (например: Appending values to dictionary in Python).

Смотрите пример:

# the API provides data like this 
def getFrame(i): 
    return {"X": 
       {"value" : i, 
       "quality": i*2}, 
      "AF3": 
       {"value" : i*3, 
       "quality": i*4} 
      } 


# object to collect single frames 
class WindowDto(object): 
    def __init__(self, windowSize, header): 
     self.header = header 
     self.windowSize = windowSize 
     self.data = {} 
     for key in self.header: 
      self.data[key] = {"value": [], "quality": []} 

    def addFrame(self, frame): 
     for key, val in frame.iteritems(): 
      field = self.data[key] 
      field["value"].append(val["value"]) 
      field["quality"].append(val["quality"]) 


# the keys of a frame are known 
header = ["X", "AF3"] 
# the max frame count is also known, but not used yet 
maxFrameCount = 8   

dto = WindowDto(maxFrameCount, header) 
for i in range(8): 
    dto.addFrame(getFrame(i)) 

print(dto.data) 
# {'X': {'quality': [0, 2, 4, 6, 8, 10, 12, 14], 'value': [0, 1, 2, 3, 4, 5, 6, 7]}, 
# 'AF3': {'quality': [0, 4, 8, 12, 16, 20, 24, 28], 'value': [0, 3, 6, 9, 12, 15, 18, 21]}} 

Я принимаю метод addFrame() является потенциально узким местом, так как у меня перебирать всю структуру. Я ищу более разумный способ выполнить операцию add. Любые предложения, как это сделать?

Я также могу изменить способ сохранения значений (например, в массиве?) Для повышения производительности. Я знаю значения заголовка и максимальный размер окна. Значения позже обрабатываются как списки (например, sum(data["X"]["values"])), но доступ завернут WindowDto.

+0

Почему, по вашему мнению, это проблема с производительностью, и какой шаблон доступа был бы лучше, чем повторение элементов в возвращаемом объекте? – tripleee

+0

Как в стороне, это совсем не похоже на OOPish. Если элементы массива связаны (т. Е. Качество [n] является парой значений [n], и они не имеют смысла друг без друга), они должны, вероятно, быть инкапсулированы в один объект для каждой пары (в основном кортеж, возможно, с некоторые украшения). – tripleee

+0

, если вы ожидаете сообщить кадры ('print (dto.data)') ближе к концу, вы можете накапливать фреймы как есть и выполнять агрегацию во время отчета. – srj

ответ

1

Профилирование, возможно, у вас уже достаточно хорошо для вашего сервера ?!

import cProfile 
cProfile.run('for i in range(128):dto.addFrame(getFrame(i))') 
     899 function calls in 0.001 seconds 
cProfile.run('for i in range(128**2):dto.addFrame(getFrame(i))') 
     114691 function calls in 0.046 seconds 
+0

Нет, я не занимался профилированием - возможно, должен был быть - это было просто ощущение, что структура, которая у меня есть на данный момент, не лучшее решение. Спасибо за код. – ppasler

+1

Вы были правы, текущая структура имела лучшую производительность, поэтому нет необходимости изменять структуру данных. – ppasler