как будет влиять на производительность огромное количество использиваний with open() python

Главный вопрос:

можно ли делать так:

for i in range(1_000_000_000):
   with open('file.txt', 'a') as f:
       #сам код

или надо всё таки надо так:

f = open('file.txt', 'a')

for i in range(1_000_000_000):
    #сам код

f.close()

примечание: цикл обезательно должен быть за with


Предыстория: У меня есть клас, в которым содержаться все методи работы с бд. Суть заключается в том, что в каждом методе используется with open(). Это удобно, но я волнуюся, что это может повлиять на производительность. В одном из примеров кода я увидел, что в def __inti__(): создают переменную с файлом db = qlite3.connect('database.db') и его используют в дальнейшем но это не удобно, файл закроеться только вместе с приложением и нет преимуществ with.

пример:

#файл database.py
class BotBD:
    def __init__(self, db_name):
        self.db_name = db_name
        with sqlite3.connect(self.db_name) as db:
            cursor = db.cursor()
            query = '''
            CREATE TABLE IF NOT EXISTS users(
            id INTEGER PRIMARY KEY,
            name VARCHAR(30),
            age INTEGER(3),
            sex INTEGER NOT NULL DEFAULT 1,
            balance INTEGER NOT NULL DEFAULT 2000,
            login VARCHAR(15),
            password VARCHAR(20)
            );
            CREATE TABLE IF NOT EXISTS casino(
            name VARCHAR(50),
            description TEXT(300),
            balance BIGINT NOT NULL DEFAULT 10000
            )
            '''
            cursor.executescript(query)

    def registration(self):
        self.name = input("Name: ")
        self.age = int(input("Age: "))
        self.sex = int(input("Sex: "))
        self.login = input("Login: ")
        self.password = input("Password: ")
        with sqlite3.connect(self.db_name) as db:
            #и далее куча кода
        

Помогите пожалуйста


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

Автор решения: vitidev

С файлами все просто.

Ничего не является бесплатным и очевидно, что "один раз открыть" намного лучше чем "открыть миллион раз". Так что нужно минимизировать открытие файлов. Но и нет смысла их удерживать открытыми сверх необходимого.

С sqlite же несколько сложнее.

В sqlite "коннект" тоже является открытием файла. Но есть нюанс - если выбрать журналирование WAL (а зачем использовать что-то другое???), то "коннект" рождает файлы журнала, а при закрытии последнего коннекта вливает журнал в основной файл. И вот такое закрытие дорого стоит.

Поэтому нужно избегать такого закрытия, если вы используете WAL

Если у вас однопоток, то вы можете открыть один коннект на старте приложения и использовать.

Если же многопоток, то технически можно использовать один коннект с оговорками, но это неудобно, поэтому проще делать connect там где нужно не забывая про правило "меньше - лучше", то есть если предстоит тяжелая работа, то открыл - поработал - закрыл.

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

Или же открыть дополнительный коннект на старте приложения, который не используется, а всего лишь мешает при закрытии других коннектов трогать файлы журнала.

→ Ссылка