• XSS.stack #1 – первый литературный журнал от юзеров форума

Как ускорить чтение файлов python?

CheckData

(L2) cache
Пользователь
Регистрация
19.05.2023
Сообщения
304
Реакции
70
Есть скрипт, который находит все файлы txt, которые находятся в определенной папке, собирает их в массив(пути), а после проверяет есть ли слово в этих txt. Как можно ускорить это? Написать на c++ и добавить в код?
 
Операции чтения записи самые требовательные и долгие. Язык менять не стоит. Стоит подумать об оптимизации. Вопрос такой - файлы всегда разные или все те же? Если всегда одинаковые то лучше конечно кешировать их внутренности в массиве с помощью pickle. Что бы было чтение одного файла при запуске программы, и требовалось только читать его. Или оптимизировать все в csv таблицу. Хз попробуй так. Если кто то поумнее меня в программировании придет то тапками не кидаться :З
 
Операции чтения записи самые требовательные и долгие. Язык менять не стоит. Стоит подумать об оптимизации. Вопрос такой - файлы всегда разные или все те же? Если всегда одинаковые то лучше конечно кешировать их внутренности в массиве с помощью pickle. Что бы было чтение одного файла при запуске программы, и требовалось только читать его. Или оптимизировать все в csv таблицу. Хз попробуй так. Если кто то поумнее меня в программировании придет то тапками не кидаться :З
Вес всегда разный
 
Последнее редактирование:
Вес всегда разный
Скрытое содержимое
О нет бро, тогда не слушай моих советов, взглянул на твой кодес, и теперь вижу что мой уровень слегка-слегка недотягивает (без сарказма, внатуре)
 
Есть скрипт, который находит все файлы txt, которые находятся в определенной папке, собирает их в массив(пути), а после проверяет есть ли слово в этих txt. Как можно ускорить это? Написать на c++ и добавить в код?
не пробовал лично, но как идея, реализовать поиск слова в файлах, через какую нибудь unix консольную утилиту, вызывать ее через сабпроцесс, кормить ей путь и парсить уже ее результат.

upd.
имхо, или вообще через баш скрипт все это делать, не прибегая к пытону :)
 
попробуй асинхронно или в многопотоке
from multiprocessing.dummy import Pool as ThreadPool

t = ThreadPool(300)
t.map(proc,file)
t.close()
t.join()

proc - функция принимающая путь и осуществляющая поиск file список путей
должно ускорить но я хз на сколько не юзал многопоток под чтение диска.


Вот тут про асинхронность она чуть сложнее
 
Последнее редактирование:
написал в асинке, на 6 секунд меньше результат XD
тогда хз :/ А если разбить и через мультипроцессинг запускать кучу процессов на каждый фаил свои процесс. если есть какие то принты убираи их чтоб результат в фаил писал. Принты пипец тормозят
 
Есть скрипт, который находит все файлы txt, которые находятся в определенной папке, собирает их в массив(пути), а после проверяет есть ли слово в этих txt. Как можно ускорить это? Написать на c++ и добавить в код?
Никак не ускорить, ни процессы ни треды ничего не поможет, только апгрейднуть железку, ссд и цпу
 
Есть скрипт, который находит все файлы txt, которые находятся в определенной папке, собирает их в массив(пути), а после проверяет есть ли слово в этих txt. Как можно ускорить это?
Это дело можно организовать обычным батником, правда не знаю, насколько увеличится профит по времени. Чтобы данный код искал кириллицу, нужно сохранить его в кодировке OEM866. В строке(8) задаёшь текст для поиска, и маску для расширений файлов (в данном случае маска *.* т.е. все файлы). Запускать из дира, где находятся файлы txt:

Bash:
@echo off
echo.
echo  Поиск по маске "Версия BIOS" начался.
echo  Это займёт пару минут. Пожалуйста ждите...
echo.
echo  Слово найдено в следующих файлах:
echo  ---------------------------------
findstr /s /i /m "\<Версия BIOS\>" *.*
echo  ---------------------------------
echo  Поиск окончен!!!
pause
 
ЧатГпт говорит вот чё:
Оптимизации в новом коде:
Многопоточность: Мы используем concurrent.futures.ThreadPoolExecutor() для создания пула потоков, который параллельно обрабатывает файлы во время проверки наличия слова.
Чтение файлов частями: В данном коде мы продолжаем использовать чтение файлов целиком. Если файлы очень большие, можно рассмотреть возможность чтения данных частями для оптимизации производительности и снижения потребления памяти.
Python:
import os
import concurrent.futures

def find_txt_files(directory):
    txt_files = []
    for root, _, files in os.walk(directory):
        for file in files:
            if file.endswith(".txt"):
                txt_files.append(os.path.join(root, file))
    return txt_files

def check_word_in_file(word, file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        return word in f.read()

if __name__ == "__main__":
    search_directory = "/path/to/your/folder"
    word_to_find = "your_word"
  
    txt_files = find_txt_files(search_directory)
  
    # Using multithreading for parallel file processing
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = [executor.submit(check_word_in_file, word_to_find, file_path) for file_path in txt_files]
        found_files = [file_path for file_path, result in zip(txt_files, concurrent.futures.as_completed(futures)) if result.result()]
  
    print("Found files containing the word '{}':".format(word_to_find))
    for file in found_files:
        print(file)
 
ЧатГпт говорит вот чё:
Оптимизации в новом коде:
Многопоточность: Мы используем concurrent.futures.ThreadPoolExecutor() для создания пула потоков, который параллельно обрабатывает файлы во время проверки наличия слова.
Чтение файлов частями: В данном коде мы продолжаем использовать чтение файлов целиком. Если файлы очень большие, можно рассмотреть возможность чтения данных частями для оптимизации производительности и снижения потребления памяти.
Python:
import os
import concurrent.futures

def find_txt_files(directory):
    txt_files = []
    for root, _, files in os.walk(directory):
        for file in files:
            if file.endswith(".txt"):
                txt_files.append(os.path.join(root, file))
    return txt_files

def check_word_in_file(word, file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        return word in f.read()

if __name__ == "__main__":
    search_directory = "/path/to/your/folder"
    word_to_find = "your_word"
 
    txt_files = find_txt_files(search_directory)
 
    # Using multithreading for parallel file processing
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = [executor.submit(check_word_in_file, word_to_find, file_path) for file_path in txt_files]
        found_files = [file_path for file_path, result in zip(txt_files, concurrent.futures.as_completed(futures)) if result.result()]
 
    print("Found files containing the word '{}':".format(word_to_find))
    for file in found_files:
        print(file)
потоки не помогут
 
потоки не помогут
Я так подумал, мультипроцессинг в твоем случае подходит, если грамотно сделать, хоть и читать один файл можно одним ядром, если у нас много файлов, мы можем разделить их по ядрам. Попробуй.

P.S но тот код что выдала гопота х#йня кншн.
 
Последнее редактирование:
Есть скрипт, который находит все файлы txt, которые находятся в определенной папке, собирает их в массив(пути), а после проверяет есть ли слово в этих txt. Как можно ускорить это? Написать на c++ и добавить в код?
Попробуйте MMF.
Python:
from mmap import mmap
from pathlib import Path


def file_search(file):
    with open(file, 'r+b') as f:
        mm = mmap(f.fileno(), 0)
        tmp = mm.readline()
        if text in tmp:
            print(f'Фраза:', text, 'найдена в файле', file)


if __name__ == '__main__':
    files = Path.cwd().glob('*.txt')
    text = b'gmail'
    for file in files:
        file_search(file)
 
Есть скрипт, который находит все файлы txt, которые находятся в определенной папке, собирает их в массив(пути), а после проверяет есть ли слово в этих txt. Как можно ускорить это? Написать на c++ и добавить в код?
никак, ни что не даст супер большую скорость и дело ни разу не в яп и коде который исползьуется
 
Можно попробовать задать буффер на чтение больше, чем по умолчанию (io.DEFAULT_BUFFER_SIZE).
open(file, 'r', new_buffer_size)
Empty buffer at EoF too
 
Так, резюмирую. Сам накануне встретился с проблемой скорости чтения файлов. Какова была задача - нужно было сравнить все строки одного файла со строками другого и записать полные дубли в третий файл. Перепробовал много методов, остановился на том, что надо грузить один из сравнимых файлов в память. По другому файлу прохожу итератором и каждую итерируемую строку ищу в памяти. Поиск происходит в отдельном процессе. Это ускоряет прогу в n раз, где n - количество задействуемых ядер. Пример кода прилагается:
Python:
def filter_lines(used, line):
    # processing
    pass


def run_filter(basepath='base.txt'):
    with open('used.txt', 'r') as used_base:
        used = used_base.read()

    with open(basepath, 'r') as main_base:
        with Pool(os.cpu_count()-1) as pool:
            with open('new_base.txt', 'w') as new_base:
                for acc in pool.imap(partial(filter_lines, used), main_base):
                    if acc is not None:
                        new_base.write(f'{acc}\n')
                        new_base.flush()

P.S важно чтобы память делилась между процессами, в данном случае рид онли поэтому без излишества просто передаю в функцию. Если проебать этот момент файл может грузиться в память для каждого процесса.
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх