>  기사  >  백엔드 개발  >  효율적인 Python 범용 개체 풀링 라이브러리를 사용하는 방법

효율적인 Python 범용 개체 풀링 라이브러리를 사용하는 방법

WBOY
WBOY앞으로
2023-05-11 16:16:06804검색

객체 풀 모드는 주로 다음 응용 프로그램 시나리오에 적합합니다.
  • 리소스가 제한된 시나리오. 예를 들어 확장성이 필요하지 않은 환경(CPU, 메모리 등의 물리적 자원이 제한되어 있음)에서는 CPU 성능이 충분히 강하지 않고, 메모리가 상대적으로 부족하고, 가비지 컬렉션, 메모리 지터가 상대적으로 큰 영향을 미치게 되며, 처리량보다 응답성이 더 중요하므로 메모리 관리 효율성을 향상해야 합니다.

  • 메모리에 있는 개체 수는 제한되어 있습니다.

  • 만드는 데 비용이 많이 드는 개체.

  • 수명이 짧고 초기화 비용이 낮은 다수의 객체를 풀링하여 메모리 할당 및 재할당 비용을 줄이고 메모리 조각화를 방지합니다.

  • Python과 같은 동적 언어의 경우 GC는 객체가 조기에 재활용되지 않도록 참조 기술을 사용합니다. 일부 시나리오에서는 객체가 생성되었음에도 불구하고 아무도 사용하지 않는 유휴 기간이 있을 수 있습니다. 재활용할 개체입니다. 보관을 위해 개체 풀에 위임할 수 있습니다.

Pond 소개

Pond는 우수한 성능, 적은 메모리 사용량 및 높은 적중률을 특징으로 하는 Python의 효율적인 일반 개체 풀입니다. 대략적인 통계를 바탕으로 빈도에 따라 자동으로 재활용하는 기능을 통해 각 개체 풀의 사용 가능한 개체 수를 자동으로 조정할 수 있습니다.

현재 Python에는 완전한 테스트 사례, 완전한 코드 주석 및 완전한 문서를 갖춘 더 나은 개체 풀링 라이브러리가 없기 때문입니다. 동시에 현재 주류 개체 풀링 라이브러리에는 스마트 자동 재활용 메커니즘이 없습니다.

Pond는 커뮤니티에서 공개한 완전한 테스트 사례, 90%가 넘는 적용률, 완전한 코드 주석 및 완전한 문서를 갖춘 Python의 최초 개체 풀링 라이브러리일 수 있습니다.

Pond는 Apache Commons Pool, Netty Recycler, HikariCP 및 Caffeine에서 영감을 받아 이들 중 많은 장점을 통합했습니다.

둘째, Pond는 아주 작은 메모리 공간에서 대략적인 계산법을 사용하여 각 개체 풀의 사용 빈도를 계산하고 자동으로 재활용합니다.

트래픽이 상대적으로 무작위적이고 평균적인 경우 기본 전략과 가중치를 사용하면 메모리 사용량을 48.85% 줄일 수 있으며 차용 적중률은 100%입니다.

효율적인 Python 범용 개체 풀링 라이브러리를 사용하는 방법

트래픽이 2/8 법칙에 더 부합할 때 기본 전략과 가중치를 사용하면 메모리 사용량을 45.7% 줄일 수 있으며 차용 적중률은 100%입니다.

효율적인 Python 범용 개체 풀링 라이브러리를 사용하는 방법

디자인 개요

Pond는 주로 FactoryDict, Counter, PooledObjectTree 및 별도의 재활용 스레드로 구성됩니다.

FactoryDict

Pond를 사용하려면 객체 팩토리 PooledObjectFactory를 구현해야 합니다. PooledObjectFactory는 객체 생성, 초기화, 파괴, 확인 및 기타 작업을 제공하며 Pond에서 호출됩니다.

따라서 객체 풀이 완전히 다른 객체 저장을 지원하기 위해 Pond는 사전을 사용하여 각 팩토리 클래스의 이름과 구현하는 팩토리 클래스의 인스턴스화된 객체를 기록합니다.

각 PooledObjectFactory에는 객체 생성, 객체 파괴, 객체가 여전히 사용 가능한지 확인, 객체 재설정의 네 가지 기능이 있어야 합니다.

특별한 점은 Pond가 객체의 자동 재설정을 지원한다는 점입니다. 일부 시나리오에서는 오염을 방지하기 위해 객체에 먼저 값을 할당하고 전달한 다음 전달한 후 재활용해야 하는 상황이 있을 수 있기 때문입니다. 이 시나리오에서는 이 기능을 구현하는 것이 좋습니다.

Counter

Counter는 대략적인 카운터를 저장합니다.

PooledObjectTree

PooleedObjectTree는 사전입니다. 각 키는 선입 선출 대기열에 해당합니다.

각 대기열에는 여러 PooleedObject가 있습니다. PooledObject는 생성 시간, 마지막 대출 시간, 실제 필요한 객체를 저장합니다.

스레드 안전성

Pond의 대여 및 재활용은 모두 스레드로부터 안전합니다. Python의 큐 모듈은 멀티스레드 프로그래밍에 적합한 FIFO(선입선출) 데이터 구조를 제공합니다. 생산자 스레드와 소비자 스레드 간에 메시지나 기타 데이터를 안전하게 전달하는 데 사용할 수 있습니다.

잠금은 호출자가 처리하며 모든 다중 스레드는 동일한 Queue 인스턴스를 사용하여 안전하고 쉽게 작업할 수 있습니다. Pond의 대여와 재활용은 모두 대기열에서 수행되므로 기본적으로 스레드로부터 안전한 것으로 간주될 수 있습니다.

대출 메커니즘

Pond를 사용하여 객체를 빌려줄 때 먼저 빌려주려는 객체 유형이 PooledObjectTree에 이미 있는지 확인합니다. 존재하는 경우 이 객체의 객체 풀이 비어 있는지 확인합니다. . 그렇다면 비어 있으면 새 항목이 생성됩니다.

개체 풀에 초과 개체가 있는 경우 대기열을 사용하여 개체를 팝업하고 이 개체가 사용 가능한지 확인합니다. 사용할 수 없는 경우 해당 Factory가 자동으로 호출되어 객체를 정리하고 파괴합니다. 동시에 Python의 GC 카운트가 지워져 GC에서 더 빨리 재활용될 수 있고 다음 항목이 사용됩니다. 사용할 수 있을 때까지 계속해서.

이 개체를 사용할 수 있으면 직접 반환됩니다. 물론, 개체 풀에서 개체를 꺼내거나 새 개체를 생성하면 Counter를 사용하여 개수를 증가시킵니다.

재활용 메커니즘

객체를 재활용할 때 대상 객체 풀이 존재하는지 확인하고, 객체 풀이 가득 차면 반환할 객체가 자동으로 파기됩니다.

그런 다음 객체가 너무 오랫동안 대여되었는지 확인합니다. 구성된 최대 시간을 초과하는 경우에도 삭제됩니다.

자동 재활용

자동 재활용은 가끔씩 실행되며 기본값은 300초입니다. 자주 사용하지 않는 개체 풀의 개체를 자동으로 정리합니다.

지침

Pond 라이브러리를 먼저 설치하고 프로젝트에서 참조할 수 있습니다.

pip install pondpond
from pond import Pond, PooledObjectFactory, PooledObject

먼저 넣으려는 객체 유형에 대한 팩토리 클래스를 선언해야 합니다. 예를 들어 아래 예에서는 풀링된 객체가 Dog가 되기를 원하므로 먼저 PooledDogFactory 클래스를 선언하고 PooledObjectFactory를 구현합니다.

class Dog:
 name: str
 validate_result:bool = True
class PooledDogFactory(PooledObjectFactory):
 def creatInstantce(self) -> PooledObject:
 dog = Dog()
 dog.name = "puppy"
 return PooledObject(dog)
 def destroy(self, pooled_object: PooledObject):
 del pooled_object
 def reset(self, pooled_object: PooledObject) -> PooledObject:
 pooled_object.keeped_object.name = "puppy"
 return pooled_object
 def validate(self, pooled_object: PooledObject) -> bool:
 return pooled_object.keeped_object.validate_result

그런 다음 Pond 객체를 생성해야 합니다.

pond = Pond(borrowed_timeout=2,
 time_between_eviction_runs=-1,
 thread_daemon=True,
 eviction_weight=0.8)

Pond는 다음을 나타내는 일부 매개변수를 전달할 수 있습니다.

borrowed_timeout: 단위는 초이며, 대여된 객체의 최대 기간이며, 기간을 초과하는 객체는 반환 시 자동으로 삭제되며 개체 풀에 포함되지 않습니다.

time_between_eviction_runs: 단위는 초, 자동 재활용 간격입니다.

thread_daemon: 데몬 스레드, True이면 기본 스레드가 닫힐 때 자동으로 재활용되는 스레드가 닫힙니다.

eviction_weight: 자동 재활용 중 가중치에 최대 사용 빈도가 곱해집니다. 사용 빈도가 이 값보다 작은 개체 풀의 개체는 정리 단계로 들어갑니다.

인스턴스화된 팩토리 클래스:

factory = PooledDogFactory(pooled_maxsize=10, least_one=False)

PooledObjectFactory를 상속하는 모든 것에는 pooled_maxsize 및 최소_1 매개변수를 전달할 수 있는 자체 생성자가 있습니다.

pooled_maxsize: 이 팩토리 클래스에서 생성된 개체 풀에 배치할 수 있는 최대 개체 수입니다.

least_one: True인 경우 자동 정리를 시작할 때 이 팩토리 클래스에서 생성된 개체의 개체 풀은 최소한 하나의 개체를 유지합니다.

Pond에 이 팩토리 객체를 등록합니다. 기본적으로 팩토리의 클래스 이름은 PooledObjectTree의 키로 사용됩니다.

pond.register(factory)

물론 이름을 사용자 정의할 수도 있으며 이름은 PooledObjectTree의 키:

pond.register(factory, name="PuppyFactory")

등록이 성공적으로 완료되면 Pond는 객체 풀이 채워질 때까지 공장에서 설정된 pooled_maxsize에 따라 자동으로 객체 생성을 시작합니다.

객체 대여 및 반환:

pooled_object: PooledObject = pond.borrow(factory)
dog: Dog = pooled_object.use()
pond.recycle(pooled_object, factory)

물론 이름으로 객체를 빌리고 반환할 수 있습니다:

pooled_object: PooledObject = pond.borrow(name="PuppyFactory")
dog: Dog = pooled_object.use()
pond.recycle(pooled_object, name="PuppyFactory")

객체 풀 완전히 지우기:

pond.clear(factory)

이름으로 객체 풀 정리:

pond.clear(name="PuppyFactory")

일반적으로 귀하만 위의 방법을 사용해야 하며 객체 생성 및 객체 재활용은 완전 자동입니다.

위 내용은 효율적인 Python 범용 개체 풀링 라이브러리를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제