У меня есть довольно большое количество наборов данных для расширения.
Мне интересно, что было бы альтернативным/более быстрым способом сделать это.
Я пробовал как iadd, так и extend, оба из них занимают довольно много времени, чтобы создать вывод.
from timeit import timeit
raw_data = [];
raw_data2 = [];
added_data = range(100000)
# .__iadd__
def test1():
for i in range(10):
raw_data.__iadd__(added_data*i);
#extend
def test2():
for i in range(10):
raw_data2.extend(added_data*i);
print(timeit(test1,number=2));
print(timeit(test2,number=2));
Я чувствую, что понимание списка или отображение массива может быть ответом на мой вопрос...
@AzatIbrakov, хорошо. спасибо, посмотрю эту функцию.
@AzatIbrakov, как было предложено, заменил time.time на timeit, спасибо!
@PatrickArtner, спасибо, тег удален.






Если вам нужны ваши данные в виде списка, вы не сильно выиграете - list.extend и __iadd__ очень близки по производительности - в зависимости от количества, которое вы используете, один или другой быстрее:
import timeit
from itertools import repeat , chain
raw_data = []
added_data = range(100000) # verify data : uncomment: range(5)
def iadd():
raw_data = []
for i in range(10):
raw_data.__iadd__(added_data)
# print(raw_data)
def extend():
raw_data = []
for i in range(10):
raw_data.extend(added_data)
# print(raw_data)
def tricked():
raw_data = list(chain.from_iterable(repeat(added_data,10)))
# print(raw_data)
for w,c in (("__iadd__",iadd),(" extend",extend),(" tricked",tricked)):
print(w,end = " : ")
print("{:08.8f}".format(timeit.timeit(c, number = 200)))
Выход:
# number = 20
__iadd__ : 0.69766775
extend : 0.69303196 # "fastest"
tricked : 0.74638002
# number = 200
__iadd__ : 6.94286992 # "fastest"
extend : 6.96098415
tricked : 7.46355973
Если вам это не нужно, вам лучше использовать генератор, который chain.from_iterable(repeat(added_data,10)) не создает сам список, чтобы уменьшить объем используемой памяти.
Связанный:
Я не уверен, что есть лучший способ сделать это, но с помощью numpy и ctypes вы можете предварительно выделить достаточно памяти для всего массива, а затем использовать ctypes.memmove для копирования данных в raw_data, который теперь представляет собой ctypes массив ctypes.c_longs.
from timeit import timeit
import ctypes
import numpy
def test_iadd():
raw_data = []
added_data = range(1000000)
for i in range(10):
raw_data.__iadd__(added_data)
def test_extend():
raw_data = []
added_data = range(1000000)
for i in range(10):
raw_data.extend(added_data)
return
def test_memmove():
added_data = numpy.arange(1000000) # numpy equivalent of range
raw_data = (ctypes.c_long * (len(added_data) * 10))() # make a ctypes array to contain elements
# the address to copy to
raw_data_addr = ctypes.addressof(raw_data)
# the length of added_data in bytes
added_data_len = len(added_data) * ctypes.sizeof(ctypes.c_long)
for i in range(10):
# copy data for one section
ctypes.memmove(raw_data_addr, added_data.ctypes.data, added_data_len)
# update address to copy to
raw_data_addr += added_data_len
tests = [test_iadd, test_extend, test_memmove]
for test in tests:
print '{} {}'.format(test.__name__, timeit(test, number=5))
Этот код дал следующие результаты на моем ПК:
test_iadd 0.648954868317
test_extend 0.640357971191
test_memmove 0.201567173004
Это показывает, что использование ctypes.memmove значительно быстрее.
пожалуйста, используйте
timeitмодуль stdlib или какой-либо другой инструмент профилирования,time.timeс выполнением в одной области видимости не подходит