python самая быстрая реализация структуры доступа - PullRequest
1 голос
/ 02 апреля 2020

У меня есть структура данных, которая состоит из фиксированного числа полей и рекурсивной функции, которая выполняет некоторую обработку списка этих структур. На каждой итерации функция обращается к какому-то конкретному элементу списка (структуре данных), анализирует все его поля и (на основе значений полей) изменяет список, удаляя или добавляя новые элементы структуры данных.

Мне было интересно, что будет наиболее эффективным способом реализации этой структуры данных? Я предполагаю, что наиболее чувствительными аспектами являются создание новой структуры и доступ к полям структуры. Я провел некоторое тестирование на структурах с 10 полями:

  1. Реализация в виде списка:
print("List")

def list_f ():
  l = [1,2,3,4,5,6,7,8,9,10]
  a1 = l[0]
  a2 = l[1]
  a3 = l[2]
  a4 = l[3]
  a5 = l[4]
  a6 = l[5]
  a7 = l[6]
  a8 = l[7]
  a9 = l[8]
  a10 = l[9]

print(timeit("list_f()", "from __main__ import list_f"))

Вывод:

List
0.4056466743350029
Реализовать как диктовку:
print("Dict")

def dict_f ():
  d = {"1":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10}
  a1 = d["1"]
  a2 = d["2"]
  a3 = d["3"]
  a4 = d["4"]
  a5 = d["5"]
  a6 = d["6"]
  a7 = d["7"]
  a8 = d["8"]
  a9 = d["9"]
  a10 = d["10"]

print(timeit("dict_f()", "from __main__ import dict_f"))

Вывод:

Dict
0.6061008963733912
Реализация как класс:
print("Class")

class C (object):

  def __init__(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10):
    self.a1 = a1
    self.a2 = a2
    self.a3 = a3
    self.a4 = a4
    self.a5 = a5
    self.a6 = a6
    self.a7 = a7
    self.a8 = a8
    self.a9 = a9
    self.a10 = a10

def class_f ():
  c = C(1,2,3,4,5,6,7,8,9,10)
  a1 = c.a1
  a2 = c.a2
  a3 = c.a3
  a4 = c.a4
  a5 = c.a5
  a6 = c.a6
  a7 = c.a7
  a8 = c.a8
  a9 = c.a9
  a10 = c.a10

print(timeit("class_f()", "from __main__ import class_f, C"))

Вывод:

Class
1.2926895800046623

Мне кажется, списки являются наиболее эффективным решением. Знаете ли вы о какой-либо другой реализации, которую я мог бы попробовать, или как эти времена выполнения могли зависеть от количества и типа полей структуры?

РЕДАКТИРОВАТЬ:

Так же, как пояснение, поля не имеют тот же тип (я только что использовал все int-ы в примере), будут некоторые строки, некоторые дескрипторы объектов и так далее ... Мне никогда не придется изменять поля на лету. Я знаю, какие значения я хочу, чтобы они имели при создании структуры, поэтому я инициализирую их и вставляю структуру в список. Функция только считывает эти значения и удаляет всю структуру из списка по окончании (и при необходимости создает совершенно новую структуру и вставляет ее в список ввода). Я тот, кто определяет и структуру, и функцию, чтобы я мог адаптировать функцию для эффективной работы с любой реализацией.

Ответы [ 4 ]

0 голосов
/ 30 апреля 2020

После некоторого дополнительного тестирования я обнаружил, что, как подсказывает @ {bruno desthuilliers}, кортеж обеспечивает самое короткое время доступа, поэтому реализовал его таким образом.

0 голосов
/ 02 апреля 2020

Списки действуют, если вы уже заранее знаете положение нужного элемента. Словари имеют преимущество в том случае, если у вас есть ключ и вы хотите получить доступ к значению, что можно сделать за постоянное время. Доступ к списку также является линейной временной операцией, но поиск в случае неизвестной позиции - нет, так как он потребует перемещения по элементам до тех пор, пока не будет найден правильный.

Основываясь на вашем описании, я бы сказал, что словари были бы наиболее понятной (как в коде ясности) структура.

0 голосов
/ 02 апреля 2020

Списки являются редактируемыми объектами, кортежи - нет, словарь - это неупорядоченная структура данных на основе ключей, а не на основе индексов в виде списков и кортежей. Говоря о производительности, кортежи и списки немного быстрее, чем словарь, но читаемость имеет значение. Поэтому, если эти значения имеют значение (возможно, a1 - высота чего-либо, a2 - ширина, a3 - количество змей в комнате и т. Д.), Вам следует рассмотреть возможность использования словаря. Если это цены BT C за последние 10 часов (одно значение для всех значений), вы можете использовать список. Кортеж не сильно используется.

0 голосов
/ 02 апреля 2020

Ответ на ваш вопрос зависит от того, какие операции вам нужно выполнить и какие типы данных вы собираетесь хранить в своем контейнере. Для примера, который вы приводите, list - это то, что имеет больше всего смысла.

Предполагая, что ваша точка зрения ускоряет ваш код, ваша альтернатива будет использовать векторизацию. Например, если вы собираетесь выполнять одну и ту же операцию для каждого элемента, а ваши элементы - числа, то вы можете использовать numpy.ndarray, который будет использовать векторизованный подход для выполнения операции по элементам. Отказ от нормального python l oop значительно сократит время выполнения.

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