Подскажите, пожалуйста, как ускорить выполнение программы? И почему она такая медленная?

Цель программы отделить русский перевод слов от немецкого значения и поместить это в разные списки. Файл, в котором находится всё это выглядит примерно вот так:

das Sedimentgestein осадочная порода

Kernspaltung расщепление атомного ядра

Im Grunde genommen по сути

...

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

Но код вышел нереально медленным, подскажите, пожалуйста, где может крыться причина этого и возможно ли это исправить?

import os
import langdetect



os.chdir(r'C:\Users\write\OneDrive\Документы\help')
slovar=[]
with open('wordd.txt', 'r') as proba:
    for line in proba:
       slovar.append(str(line))
       
lange_slovar=len(slovar)

from langdetect import detect


deut=[]
rus=[]
deut2=[]
rus2=[]
k=0

while k!=lange_slovar:
    a=slovar[k] 
    d=a.split(' ') 
    for word in d:
        try:
            if (detect(str(word))!='uk' and
                detect(str(word))!='ru' and
                detect(str(word))!='mk' and
                detect(str(word))!='bg') :
                
                deut.append(word) #здесь хранится немецкое словосочетание или слово
                
            else:
                rus.append(word) #русское словосочетание или слово
        except:
            pass
    MyString=' '.join(deut) 
    deut2.append(MyString)
    rus2.append(rus)
    deut=[]
    rus=[]
    

    k+=1
    

print(' ')

rus2=[x for x in rus2 if x!=''] #удаление пустых элементов в русском списке, в немецком все ок

import random

a=random.choice(rus2)
for i in a:
   print(i)

Ответы (1 шт):

Автор решения: CrazyElf
  • Вы как-то странно читаете файл, есть же готовая функция readlines, которая вернёт вам сразу весь файл в виде списка строк, самому их не надо читать и в список добавлять
  • Но на самом деле вам и не нужен весь файл со словарём в памяти, вы только зря тратите время на добавление в список и т.д., обрабатывайте файл построчно, сразу пускайте строки на обработку, зачем вам промежуточный список?
  • Вы много где зачем-то лишний раз преобразуете строку в строку через str, это излишне, у вас и так уже строка
  • Скорее всего медленно работает функция detect, очень рекомендую сделать свою функцию, обёрнутую кэширующим декоратором lru_cache и вызывать detect через эту функцию. Если слова у вас в файле довольно часто повторяются, это может дать заметное ускорение (в несколько раз, иногда на порядок).
  • Вы ещё и вызываете detect(str(word)) несколько раз подряд во время проверки. Не делайте так. Помещайте результат работы функции в переменную и потом в if проверяйте значение этой переменной. Кэширование поможет справиться и с этим, но так лучше не делать никогда.

Пример использования кэширующего декоратора (с применением двух других советов):

from functools import lru_cache

@lru_cache
def detect_cached(word):
    return detect(word)

...

det = detect_cached(word)
if (det!='uk' and
    det!='ru' and
    det!='mk' and
    det!='bg') :
...
→ Ссылка