Самое важное для оптимизации - понять, что именно работает плохо. Тогда вы увидите, что можно оптимизировать.
Если, например, чтение и запись занимают 99% времени, на самом деле не стоит оптимизировать обработку ваших данных. Даже если бы вы могли ускорить обработку на 10, вы бы просто получили 0,9%, если бы чтение и запись потребляло 99%
Я предлагаю измерить и сравнить некоторые версии и опубликовать различия в производительности. Это может привести к потенциальным дальнейшим предложениям по оптимизации.
Во всех приведенных ниже примерах я заменил writelines
на write
, поскольку строки письма, вероятно, разлагают ваш строчный символ за символом перед записью.
В любом случае. Вы хотите использовать write
У вас уже должно быть ускорение примерно на 5.
1.) Просто чтение и запись
with open(corpus_in,"rt") as corpus_input, open(corpus_out,"wt")
as corpus_out:
for line in corpus_input:
corpus_out.write(line)
2.) Просто чтение и запись с большим буфером
import io
BUF_SIZE = 50 * io.DEFAULT_BUFFER_SIZE # try other buffer sizes if you see an impact
with open(corpus_in,"rt", BUF_SIZE) as corpus_input, open(corpus_out,"wt", BUF_SIZE)
as corpus_out:
for line in corpus_input:
corpus_out.write(line)
Для меня это увеличивает производительность на несколько процентов
3.) переместить поисковое регулярное выражение и генерацию замены из l oop.
rules = []
for word in dict_keys:
rules.append((re.compile(fr'\b{word}\b'), word + "_lorem_ipsum"))
for line in corpus_input:
for regexp, new_word in rules:
line = regexp.sub(new_word, line)
corpus_out.write(line)
На моей машине с моей частотой строк, содержащих слова, это решение фактически медленнее, чем решение, имеющее строку if word in line
Так что, возможно, попробуйте: 3.a) переместить поисковое регулярное выражение и генерацию замены из l oop.
rules = []
for word in dict_keys:
rules.append((word, re.compile(fr'\b{word}\b'), word + "_lorem_ipsum"))
for line in corpus_input:
for word, regexp, new_word in rules:
if word in line:
line = regexp.sub(new_word, line)
corpus_out.write(line)
3.b) Если все замещающие строки длиннее исходных, это будет немного быстрее.
rules = []
for word in dict_keys:
rules.append((word, re.compile(fr'\b{word}\b'), word + "_lorem_ipsum"))
for line in corpus_input:
temp_line = line
for word, regexp, new_word in rules:
if word in line:
temp_line = regexp.sub(new_word, temp_line)
corpus_out.write(temp_line)
4. ), если вы действительно замените всегда на word + "_lorem_ipsum"
, объедините регулярное выражение в одно.
regexp = re.compile(fr'\b({"|".join(dict_keys)})\b')
for line in corpus_input:
line = regexp.sub("\1_lorem_ipsum", line)
corpus_out.write(line)
4.a) в зависимости от распределения слов это может быть быстрее:
regexp = re.compile(fr'\b({"|".join(dict_keys)})\b')
for line in corpus_input:
if any(word in line for word in dict_keys):
line = regexp.sub("\1_lorem_ipsum", line)
corpus_out.write(line)
Независимо от того, это более эффективно или нет, вероятно, зависит от количества слов для поиска и заменить и частота этих слов. У меня нет этой даты.
Для 5 слов и моего распределения медленнее, чем 3.a
5) если заменяемые слова разные, вы все равно можете попытаться объединить регулярные выражения и использовать функция для замены
replace_table = {
"word1": "word1_laram_apsam",
"word2": "word2_lerem_epsem",
"word3": "word3_lorom_opsom",
}
def repl(match):
return replace_table[match.group(1)]
regexp = re.compile(fr'\b({"|".join(dict_keys)})\b')
for line in corpus_input:
line = regexp.sub(repl, line)
corpus_out.write(line)
Медленнее 5 или лучше, чем 3.a, зависит от количества слов и распределения / частоты wird.