Python для цикла замедляется из-за большого списка - PullRequest
0 голосов
/ 23 июня 2019

Так что в настоящее время у меня есть цикл for, который заставляет программу python умирать с программой, говорящей «Killed». Он замедляет примерно 6000 элементов, а программа медленно умирает на отметке 6852 элементов списка. Как мне это исправить?

Полагаю, это из-за того, что список слишком велик.

Я попытался разделить список на две части вокруг 6000. Возможно, это связано с управлением памятью или чем-то еще. Помощь будет оценена.

    for id in listofids:
        connection = psycopg2.connect(user = "username", password = "password", host = "localhost", port = "5432", database = "darkwebscraper")

        cursor = connection.cursor()
        cursor.execute("select darkweb.site_id, darkweb.site_title, darkweb.sitetext from darkweb where darkweb.online='true' AND darkweb.site_id = %s", ([id]))
        print(len(listoftexts))

        try:
            row = cursor.fetchone()
        except:
            print("failed to fetch one")
        try:
            listoftexts.append(row[2])
            cursor.close()
            connection.close()
        except:
            print("failed to print")

1 Ответ

1 голос
/ 23 июня 2019

Вы правы, это, вероятно, потому, что список становится большим: список python - это непрерывные пробелы в памяти.Каждый раз, когда вы добавляете в список, python проверяет, есть ли место в следующей позиции, и если нет, он перемещает весь массив куда-то, где достаточно места.Чем больше ваш массив, тем больше Python имеет для перемещения.

Одним из способов будет заранее создать массив нужного размера.

РЕДАКТИРОВАТЬ: Просто чтобы убедиться, что это было ясно, я составил пример, чтобы проиллюстрировать мою точку зрения.Я сделал 2 функции.Первый добавляет строковый индекс (чтобы увеличить его) к списку на каждой итерации, а другой просто заполняет пустой массив:

import numpy as np
import matplotlib.pyplot as plt
from time import time

def test_bigList(N):
    L = []
    times = np.zeros(N,dtype=np.float32)

    for i in range(N):
        t0 = time()
        L.append(str(i))
        times[i] = time()-t0

    return times

def test_bigList_numpy(N):
    L = np.empty(N,dtype="<U32")
    times = np.zeros(N,dtype=np.float32)

    for i in range(N):
        t0 = time()
        L[i] = str(i)
        times[i] = time()-t0
    return times

N = int(1e7)
res1 = test_bigList(N)
res2 = test_bigList_numpy(N)

plt.plot(res1,label="list")
plt.plot(res2,label="numpy array")
plt.xlabel("Iteration")
plt.ylabel("Running time")
plt.legend()
plt.title("Evolution of iteration time with the size of an array")
plt.show()

Я получаю следующий результат:

enter image description here

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

Если это не сработает, то это может быть связано с самой базой данных, но я могу 'не поможет вам, не зная специфики базы данных.

...