πŸπŸ’Ύ Π’Π²ΠΎΠΉ Python-ΠΊΠΎΠ΄ ΠΆΡ€Π΅Ρ‚ ΠΏΠ°ΠΌΡΡ‚ΡŒ? Π’ΠΎΡ‚ 11 способов это ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ

НСвозмоТно Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ высокой ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΠΈ, Ссли ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ нСэффСктивно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ. РасскаТСм, ΠΊΠ°ΠΊ это ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ.

ΠŸΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ – ΠΊΠ»ΡŽΡ‡ ΠΊ созданию эффСктивного ΠΈ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. Π’ распоряТСнии Python-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Π΅ΡΡ‚ΡŒ встроСнныС ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹, сторонниС инструмСнты ΠΈ кастомныС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ ΡΠΎΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ расход памяти.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹ΠΉ ΠΏΡƒΠ»

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹ΠΉ ΠΏΡƒΠ»

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹ΠΉ ΠΏΡƒΠ» – стратСгия ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ памяти ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, которая позволяСт ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹:

  • ВмСсто создания Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±Π΅Ρ€Π΅Ρ‚ Π΅Π³ΠΎ ΠΈΠ· ΠΏΡƒΠ»Π°.
  • Новый ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ создаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли Π² ΠΏΡƒΠ»Π΅ Π½Π΅Ρ‚ доступных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².
  • ПослС использования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ возвращаСтся Π² ΠΏΡƒΠ», Π° Π½Π΅ уничтоТаСтся.

Если ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° постоянно создаСт ΠΈ удаляСт рСсурсоСмкиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Ρ‚ΠΎ этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚:

  • Π‘Π½ΠΈΠ·ΠΈΡ‚ΡŒ Π·Π°Ρ‚Ρ€Π°Ρ‚Ρ‹ Π½Π° Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈ освобоТдСниС памяти.
  • Π£ΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π½Π° сборщик мусора.
  • ΠŸΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠ΄Π°, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ с Π·Π°Ρ‚Ρ€Π°Ρ‚Π½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ ΠΏΡƒΠ»Π°:

class ObjectPool:
    def __init__(self, create_func):
        self.create_func = create_func  
        self.pool = []  

    def acquire(self):
        """ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΡƒΠ»Π° ΠΈΠ»ΠΈ создаСм Π½ΠΎΠ²Ρ‹ΠΉ"""
        if self.pool:
            obj = self.pool.pop()
            print("Взяли ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΡƒΠ»Π°")
            return obj
        print("Π‘ΠΎΠ·Π΄Π°Π½ Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚")
        return self.create_func()   

    def release(self, obj):
        """Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² ΠΏΡƒΠ»"""
        self.pool.append(obj)
        print("ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ Π² ΠΏΡƒΠ»")

def create_expensive_object():
    print("Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ рСсурсоСмкий ΠΎΠ±ΡŠΠ΅ΠΊΡ‚")
    return [0] * 1000000  

pool = ObjectPool(create_expensive_object)
obj1 = pool.acquire()
pool.release(obj1) 
"""Π‘Π΅Ρ€Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ снова (ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ obj1)"""
obj2 = pool.acquire()

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

Π‘ΠΎΠ·Π΄Π°Π½ Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚
Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ рСсурсоСмкий ΠΎΠ±ΡŠΠ΅ΠΊΡ‚
ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ Π² ΠΏΡƒΠ»
Взяли ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΡƒΠ»Π°

Π‘Π»Π°Π±Ρ‹Π΅ ссылки

Π‘Π»Π°Π±Ρ‹Π΅ ссылки

Π’ Python ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ сборщик мусора, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ удаляСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΠ³Π΄Π° Π½Π° Π½ΠΈΡ… Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ ссылок. Но ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ссылку Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π½Π΅ мСшая Π΅Π³ΠΎ автоматичСскому ΡƒΠ΄Π°Π»Π΅Π½ΠΈΡŽ. Π‘Π»Π°Π±Ρ‹Π΅ ссылки ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±Π΅Π· увСличСния Π΅Π³ΠΎ счСтчика ссылок, ΠΈ Ρ‚Π΅ΠΌ самым ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ потрСблСния памяти – ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ автоматичСски ΡƒΠ΄Π°Π»ΡΡ‚ΡŒΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ большС Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ:

  • Для кэшСй – Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ автоматичСски ΡƒΠ΄Π°Π»ΡΠ»ΠΈΡΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ большС Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹.
  • Для избСТания цикличСских ссылок – Ссли ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ A ссылаСтся Π½Π° B, Π° B Π½Π° A, ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ сборщик мусора ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡ… Π½Π΅ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования слабых ссылок:

import weakref

class ExpensiveObject:
    def __init__(self, value):
        self.value = value

def on_delete(ref):
    print("ΠžΠ±ΡŠΠ΅ΠΊΡ‚ ΡƒΠ΄Π°Π»Π΅Π½")

obj = ExpensiveObject(555_555_555)
weak_ref = weakref.ref(obj, on_delete) 
del obj
print(weak_ref())  

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

ΠžΠ±ΡŠΠ΅ΠΊΡ‚ ΡƒΠ΄Π°Π»Π΅Π½
None

Π‘Π»ΠΎΡ‚Ρ‹

Π‘Π»ΠΎΡ‚Ρ‹

Π’ Python ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ класса ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ __dict__ для хранСния своих Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ². Π­Ρ‚ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ ΡΡ€Π°Π²Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ большой объСм памяти, особСнно Ссли создаСтся ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

Если ΠΌΡ‹ Π·Π°Ρ€Π°Π½Π΅Π΅ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Ρƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ __slots__, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ. Π­Ρ‚ΠΎ позволяСт Python ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ массив фиксированного Ρ€Π°Π·ΠΌΠ΅Ρ€Π° вмСсто словаря. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π½ΠΈΠΆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π² RegularClass всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ хранят Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ Π² словарС, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΈΡ… Π³ΠΈΠ±ΠΊΠΈΠΌΠΈ, Π½ΠΎ Π·Π°Ρ‚Ρ€Π°Ρ‚Π½Ρ‹ΠΌΠΈ ΠΏΠΎ памяти, Π° SlottedClass вмСсто словаря ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½Ρ‹ΠΉ массив для сниТСния потрСблСния памяти:

class RegularClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class SlottedClass:
    __slots__ = ['x', 'y']
    def __init__(self, x, y):
        self.x = x
        self.y = y

import sys

regular = RegularClass(1, 2)
slotted = SlottedClass(1, 2)
"""Π Π°Π·Π½ΠΈΡ†Π° зависит ΠΎΡ‚ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ ΠΈ вСрсии Python"""
print(sys.getsizeof(regular))  
print(sys.getsizeof(slotted))  

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

56
48

ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ

ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ

Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΎΡ‡Π΅Π½ΡŒ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ нСэффСктивной ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ. Π Π΅ΡˆΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ° отобраТСния Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ – ΠΎΠ½Π° позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ρ„Π°ΠΉΠ»ΠΎΠΌ, ΠΊΠ°ΠΊ с ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ массивом, Π±Π΅Π· нСобходимости Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ содСрТимоС ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΠΎΠΆΠ½ΠΎ быстро Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² Ρ„Π°ΠΉΠ», обрабатывая Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΡƒΠΆΠ½Ρ‹Π΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹. Python прСдоставляСт ΠΌΠΎΠ΄ΡƒΠ»ΡŒ mmap, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π½ΠΈΠΌ, ΠΊΠ°ΠΊ с Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΌ массивом:

import mmap

with open('large_file.bin', 'rb') as f:
    mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)  
    # Π§ΠΈΡ‚Π°Π΅ΠΌ 100 Π±Π°ΠΉΡ‚, начиная с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ 1000
    data = mm[1000:1100]
    mm.close()  # Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅

ΠœΠΎΠ΄ΡƒΠ»ΡŒ mmap особСнно ΠΏΠΎΠ»Π΅Π·Π΅Π½:

  • ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΎΠ³Ρ€ΠΎΠΌΠ½Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ.
  • Для быстрого случайного доступа ΠΊ Π΄Π°Π½Π½Ρ‹ΠΌ Π² Ρ„Π°ΠΉΠ»Π΅ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π»ΠΎΠ³ΠΎΠ² ΠΈΠ»ΠΈ Π±ΠΈΠ½Π°Ρ€Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…).
  • ΠŸΡ€ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠΌ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ частСй Ρ„Π°ΠΉΠ»Π° – mmap позволяСт ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ, ΠΊΠ°ΠΊ ΠΊ массиву, Π±Π΅Π· Π»ΠΈΡˆΠ½ΠΈΡ… дисковых ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ.

Π’ΠΎΡ‡Π½ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ объСма памяти, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ

Π’ΠΎΡ‡Π½ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ объСма памяти, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ

Если ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ слишком ΠΌΠ½ΠΎΠ³ΠΎ памяти, Π²Π°ΠΆΠ½ΠΎ Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² этом задСйствованы. ΠœΠ΅Ρ‚ΠΎΠ΄ sys.getsizeof() позволяСт ΡƒΠ·Π½Π°Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π½ΠΎ Π½Π΅ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ структуры. НапримСр, Ρƒ списка sys.getsizeof(my_list) ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΅Π³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, Π½ΠΎ Π½Π΅ элСмСнты Π²Π½ΡƒΡ‚Ρ€ΠΈ. Для Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° потрСблСния памяти Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ инструмСнты, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, memory_profiler. Π­Ρ‚ΠΎΡ‚ инструмСнт позволяСт ΠΈΠ·ΠΌΠ΅Ρ€ΡΡ‚ΡŒ использованиС памяти построчно, выявляя ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ½Ρ‹Π΅ мСста Π² ΠΊΠΎΠ΄Π΅:

from memory_profiler import profile

@profile
def memory_hungry_function():
    list_of_lists = [[i] * 1000 for i in range(1000)]
    return sum(sum(sublist) for sublist in list_of_lists)

memory_hungry_function()

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
     3     25.7 MiB     25.7 MiB           1   @profile
     4                                         def memory_hungry_function():
     5     33.4 MiB      7.7 MiB        1003       list_of_lists = [[i] * 1000 for i in range(1000)]  
     6     33.4 MiB      0.0 MiB        2003       return sum(sum(sublist) for sublist in list_of_lists)  

🐍 Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° питониста
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° питониста»
πŸπŸŽ“ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Python для собСса
ΠŸΠΎΠ΄Ρ‚ΡΠ½ΡƒΡ‚ΡŒ свои знания ΠΏΠΎ Python Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Python для собСса»
🐍🧩 Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ Python
Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ Python для ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ PythonΒ»

ЭффСктивная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΉ

ЭффСктивная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΉ

ΠžΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ список Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ всС Π΄Π°Π½Π½Ρ‹Π΅ сразу, ΠΈ Ссли Ρ„Π°ΠΉΠ» ΠΎΡ‡Π΅Π½ΡŒ большой, ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΡΡ‚ΡŒ слишком ΠΌΠ½ΠΎΠ³ΠΎ памяти:

def load_all_lines(filename):
    with open(filename, 'r') as f:
        return [process_line(line) for line in f]  

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈ yield Ρ€Π΅ΡˆΠ°ΡŽΡ‚ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ – Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ построчно, Π½Π΅ загруТая всС содСрТимоС Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ:

def process_large_dataset(filename):
    with open(filename, 'r') as f:
        for line in f:
            yield process_line(line)

for result in process_large_dataset('large_file.txt'):
    print(result)

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ стоит ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈ:

  • ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² (Π»ΠΎΠ³ΠΎΠ², CSV, JSON).
  • Π Π°Π±ΠΎΡ‚Π΅ с ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ… (Π²Π΅Π±-скрапинг, Ρ€Π°Π±ΠΎΡ‚Π° с API).
  • ΠŸΡ€ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚Π΅ΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, бСсконСчныС ряды чисСл).

НапримСр, Ρ‚Π°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΡΠ»ΠΎΠ²Π½ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ объСмного тСкстового Ρ„Π°ΠΉΠ»Π°:

def word_count_generator(file_path):
    with open(file_path, 'r') as file:
        for line in file:
            for word in line.split():
                yield word  

word_counts = {}
for word in word_count_generator('large_text_file.txt'):
    word_counts[word] = word_counts.get(word, 0) + 1

print(word_counts)

ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹Π΅ структуры Π΄Π°Π½Π½Ρ‹Ρ…

ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹Π΅ структуры Π΄Π°Π½Π½Ρ‹Ρ…

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΎΡ‡Π΅Π½ΡŒ большими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ список list ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΡΡ‚ΡŒ слишком ΠΌΠ½ΠΎΠ³ΠΎ памяти. Π’ Ρ‚Π°ΠΊΠΈΡ… случаях ΠΌΠΎΠΆΠ½ΠΎ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‡Π°ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° дискС, Π° Π½Π΅ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти. Π‘ этой Ρ†Π΅Π»ΡŒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ кастомный список, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ автоматичСски сохраняСт Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° диск, Ссли ΠΎΠ½ становится слишком большим. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π½ΠΈΠΆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ DiskBackedList – это Π³ΠΈΠ±Ρ€ΠΈΠ΄ списка ΠΈ Ρ„Π°ΠΉΠ»Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΎΠ³Ρ€ΠΎΠΌΠ½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π±Π΅Π· пСрСполнСния памяти:

  • Π₯Ρ€Π°Π½ΠΈΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти self.memory_list.
  • Если элСмСнтов становится слишком ΠΌΠ½ΠΎΠ³ΠΎ max_memory_items, ΠΎΠ½ сбрасываСт ΠΈΡ… Π² Ρ„Π°ΠΉΠ».
  • ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Ρ‚ΡŒ элСмСнты, загруТая ΠΈΡ… с диска ΠΏΡ€ΠΈ нСобходимости.
import pickle

class DiskBackedList:
    def __init__(self, max_memory_items=1000):
        self.max_memory_items = max_memory_items  # Π›ΠΈΠΌΠΈΡ‚ хранСния Π² памяти
        self.memory_list = []  
        self.disk_file = 'temp_list.pkl'  

    def append(self, item):
        """ДобавляСт элСмСнт Π² список, выгруТая Π½Π° диск ΠΏΡ€ΠΈ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠΈ Π»ΠΈΠΌΠΈΡ‚Π°"""
        self.memory_list.append(item)
        if len(self.memory_list) >= self.max_memory_items:
            self._write_to_disk()

    def _write_to_disk(self):
        """ЗаписываСт список Π½Π° диск ΠΈ ΠΎΡ‡ΠΈΡ‰Π°Π΅Ρ‚ ΠΏΠ°ΠΌΡΡ‚ΡŒ"""
        with open(self.disk_file, 'ab') as f:  # 'ab' = Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Ρ„Π°ΠΉΠ» (binary)
            pickle.dump(self.memory_list, f)
        self.memory_list.clear()  # ΠžΡ‡ΠΈΡ‰Π°Π΅ΠΌ список ΠΈΠ· памяти

    def __iter__(self):
        """Π˜Ρ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ сначала ΠΏΠΎ памяти, Π·Π°Ρ‚Π΅ΠΌ ΠΏΠΎ Ρ„Π°ΠΉΠ»Ρƒ"""
        yield from self.memory_list
        with open(self.disk_file, 'rb') as f:
            while True:
                try:
                    yield from pickle.load(f)  # Π§ΠΈΡ‚Π°Π΅ΠΌ сохранСнныС Π΄Π°Π½Π½Ρ‹Π΅
                except EOFError:
                    break  # Достигли ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°

    def __del__(self):
        """УдаляСм Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°"""
        import os
        if os.path.exists(self.disk_file):
            os.remove(self.disk_file)

ЭффСктивная Ρ€Π°Π±ΠΎΡ‚Π° с большими массивами NumPy

ЭффСктивная Ρ€Π°Π±ΠΎΡ‚Π° с большими массивами NumPy

Аналитикам ΠΈ Π΄Π°Ρ‚Π°-сайСнтистам Π½Π΅Ρ€Π΅Π΄ΠΊΠΎ случаСтся Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с массивами, Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΌΠΈ ΡΠΎΠ»ΠΈΠ΄Π½ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти. РСшСниС – ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ np.memmap: ΠΎΠ½ позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с массивом, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Ρ‚ΠΎ ΠΎΠ½ находится Π² памяти (Π° Π½Π° самом Π΄Π΅Π»Π΅ хранится Π½Π° дискС). Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с массивами, Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ объСм ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти:

import numpy as np

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ массива Π² памяти
shape = (10000, 10000)  
mm_array = np.memmap('mm_array.dat', dtype='float32', mode='w+', shape=shape)

# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ массив, ΠΊΠ°ΠΊ Ссли Π±Ρ‹ ΠΎΠ½ Π±Ρ‹Π» Π² памяти
mm_array[0, 0] = 1.0
mm_array[9999, 9999] = 100.0

# ИзмСнСния автоматичСски Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π½Π° диск
del mm_array  # Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Ρ„Π°ΠΉΠ»

ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹ΠΉ кэш с автоматичСским ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…

ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹ΠΉ кэш с автоматичСским ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…

Π’ Π΄ΠΎΠ»Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… сСрвСрных прилоТСниях Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Π² памяти Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ускоряСт Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π½Π° Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…. Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΡ‚ΡŒΡΡ с ΡƒΡ‚Π΅Ρ‡ΠΊΠΎΠΉ памяти, стоит Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ кастомный кэш с ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ Π΄Π°Π½Π½Ρ‹Ρ…. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π½ΠΈΠΆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ TimedCache:

  • Π₯Ρ€Π°Π½ΠΈΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ Π² словарС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ быстрый доступ.
  • Π—Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ врСмя добавлСния ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
  • УдаляСт ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ.
import time

class TimedCache:
    def __init__(self, expiration_time):
        self.cache = {}
        self.expiration_time = expiration_time

    def get(self, key):
        if key in self.cache:
            value, timestamp = self.cache[key]
            if time.time() - timestamp < self.expiration_time:
                return value
            else:
                del self.cache[key]
        return None

    def set(self, key, value):
        self.cache[key] = (value, time.time())

    def clean(self):
        current_time = time.time()
        self.cache = {k: v for k, v in self.cache.items() 
                      if current_time - v[1] < self.expiration_time}

# Usage
cache = TimedCache(expiration_time=60)  # ВрСмя ΠΆΠΈΠ·Π½ΠΈ кэша
cache.set('user_1', {'name': 'Alice', 'age': 30})
print(cache.get('user_1'))  
time.sleep(61) # Π”Π°Π½Π½Ρ‹Π΅ ΡƒΡΡ‚Π°Ρ€Π΅Π²Π°ΡŽΡ‚
print(cache.get('user_1'))  

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

{'name': 'Alice', 'age': 30}
None

ИспользованиС контСкстных ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ΠΎΠ² для управлСния Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ

ИспользованиС контСкстных ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ΠΎΠ² для управлСния Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ

Когда ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ создаСт ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π²Π°ΠΆΠ½ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ послС ΠΈΡ… использования. ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚Π½Ρ‹Π΅ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Ρ‹ with ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ ΠΎΡ‡ΠΈΡ‰Π°Ρ‚ΡŒ рСсурсы, Π΄Π°ΠΆΠ΅ Ссли происходит ошибка

class TempResource:
    def __init__(self):
        self.data = [0] * 1000000  

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        del self.data  

with TempResource() as resource:
    # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚
    pass  # ПослС Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· Π±Π»ΠΎΠΊΠ° self.data удалится автоматичСски

Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ особСнно ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, соСдинСниями, Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ рСсурсами, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½ΠΎ своСврСмСнно ΠΎΡ‡ΠΈΡ‰Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π»ΠΈ ΡƒΡ‚Π΅Ρ‡ΠΊΠΈ памяти.

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… Π² pandas

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… Π² pandas

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с большими Ρ‚Π°Π±Π»ΠΈΡ†Π°ΠΌΠΈ, состоящими ΠΈΠ· ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ΠΎΠ² строк, нСэффСктивно Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ вСсь Ρ„Π°ΠΉΠ» Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ. Pandas позволяСт ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ порциями (Ρ‡Π°Π½ΠΊΠ°ΠΌΠΈ), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π½Π° ΠΏΠ°ΠΌΡΡ‚ΡŒ:

import pandas as pd

def process_large_csv(file_path, chunk_size=10000):
    for chunk in pd.read_csv(file_path, chunksize=chunk_size):
        # Process each chunk
        processed_chunk = chunk.apply(some_processing_function)
        yield processed_chunk

for processed_data in process_large_csv('large_dataset.csv'):
    # ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…
    print(processed_data.head())

Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΈΠ΄Π΅Π°Π»Π΅Π½ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ Π² дСсятки Π³ΠΈΠ³Π°Π±Π°ΠΉΡ‚:

  • ЗагруТаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° Ρ‡Π°ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ… Π·Π° Ρ€Π°Π·.
  • МоТно Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с Ρ‡Π°Π½ΠΊΠ°ΠΌΠΈ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ.
  • МоТно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ для ускорСния процСсса.

Π’ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ β€” это сочСтаниС встроСнных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π²Π½Π΅ΡˆΠ½ΠΈΡ… инструмСнтов ΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΉ. Если ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒ Ρ‚Π΅Ρ…Π½ΠΈΠΊΡƒ ΠΏΠΎΠ΄ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ, ΠΌΠΎΠΆΠ½ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ ΠΏΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½ΠΈΠ΅ рСсурсов.

***

ΠŸΡ€ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ использовалась публикация 6 Powerful Python Techniques for Efficient Memory Management.

ΠŸΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅:

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

admin
11 дСкабря 2018

ООП Π½Π° Python: ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python допускаСт Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΠΈ, Π½ΠΎ Π² Π΅Π³ΠΎ основС...
admin
28 июня 2018

3 самых Π²Π°ΠΆΠ½Ρ‹Ρ… сфСры примСнСния Python: возмоТности языка

БущСствуСт мноТСство областСй примСнСния Python, Π½ΠΎ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ особСнно...
admin
13 фСвраля 2017

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python: ΠΎΡ‚ Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ° Π΄ΠΎ профСссионала

Пошаговая инструкция для всСх, ΠΊΡ‚ΠΎ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒΒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python...