Ruby의 OpenStruct에 대한 대안
OpenStruct
를 사용하는 것에 관한 것입니다. OpenStruct
에 대한 대안을 위한 시간입니다.OpenStruct
를 사용하면 메서드를 통해 키에 액세스할 수 있는 일종의 해시를 만드는 빠른 방법입니다. 그러나 OpenStruct
에는 큰 단점이 있습니다. this 및 this 소스에 따르면 성능에 대한 우려가 있습니다. 루보캅says :Instantiation of an
OpenStruct
invalidates Ruby global method cache as it causes dynamic method definition during program runtime. This could have an effect on performance, especially in case of single-threaded applications with multipleOpenStruct
instantiations.
따라서 OpenStruct를 사용하는 것이 대부분의 경우 반패턴이라면 OpenStruct에 대한 좋은 대안은 무엇이며 Ruby 3.1.2에서 이를 어떻게 벤치마킹합니까?
우선: using
OpenStruct
이 유효한 경우가 있습니다. 한 번만 실행되는 Ruby 스크립트를 만드시겠습니까? 자신의 재량에 따라 OpenStruct
를 사용하고 실행하고 스크립트를 버리십시오. 매우 자주 사용되는 Rails 애플리케이션에서 OpenStruct
를 사용합니까? 그렇게 하지 말고 아래의 대안을 확인하십시오. 내 요점은: 인터넷에서 나와 같은 임의의 사람이 각각의 모든 경우에 해야 할 일을 말하도록 하지 마십시오.OpenStruct
OpenStruct
에 대한 간단한 복습부터 시작하겠습니다.require 'ostruct'
car = OpenStruct.new
car.wheels = 4
car.mileage = 13_337
puts "My car has {car.wheels} wheels and"
puts "a mileage of #{car.mileage} miles"
# => My car has 4 wheels and
# => a mileage of 13337 miles
아주 멋진. 구문은 매우 깨끗하고 역동적이며 작업하기 쉽습니다. 이제 250,000번 해봅시다.
require 'benchmark'
require 'ostruct'
cars = []
time = Benchmark.measure do
250_000.times do
car = OpenStruct.new
car.wheel = 4
car.mileage = rand((1..100_000))
cars << car
end
end
puts time
# => 6.662331 0.400225 7.062556 ( 7.062667)
7.06초가 걸렸다. 몇 가지 대안을 계속 살펴보겠습니다.
수업
좋은 노인
class
. 필요할 때 항상 Ruby에 있습니다. 위OpenStruct
에 대한 대안으로 고객 클래스를 사용하면 다음과 같습니다.class Car
attr_accessor :wheels, :mileage
end
cars = []
time = Benchmark.measure do
250_000.times do
car = Car.new
car.wheels = 4
car.mileage = rand((1..100_000))
cars << car
end
end
puts time
# => 0.091187 0.000000 0.091187 ( 0.101195)
이번에는 0.10초가 걸렸다.
OpenStruct
를 사용하는 것보다 70배 빠릅니다.class
를 사용하는 것이 좋은 대안입니다. 더 많은 코드가 필요하지만 괜찮습니다. 그리고 이 경우 class
를 사용하면 비즈니스 도메인의 이 부분이 어떻게 생겼는지 알 수 있습니다.구조체
물론
Struct
도 살펴봐야 합니다.car_struct = Struct.new(:wheels, :mileage)
cars = []
time = Benchmark.measure do
250_000.times do
cars << car_struct.new(4, rand((1..100_000)))
end
end
puts time
# => 0.085577 0.000649 0.086226 ( 0.086235)
Struct
의 경우 class
를 사용하는 것과 유사하게 0.09초가 걸렸습니다.해시시
마지막 대안은 일반 해시입니다.
cars = []
time = Benchmark.measure do
250_000.times do
cars << { wheels: 4, mileage: rand((1..100_000)) }
end
end
puts time
# => 0.085295 0.000000 0.085295 ( 0.085301)
그리고 해시는 실행 시간이 0.09초인
class
또는 Struct
를 사용하는 것과 유사합니다.기준
요약:
OpenStruct - 6.66 0.40 7.06 (7.06) - baseline
Custom class - 0.09 0.00 0.09 (0.10) - ~70 times faster
Struct - 0.08 0.00 0.08 (0.08) - ~80 times faster
Hash - 0.08 0.00 0.08 (0.08) - ~80 times faster
무엇을 선택해야 합니까?
OpenStruct
의 위의 대안 중 하나가 좋습니다. 성능의 마지막 몇 퍼센트를 짜내고 싶다면 Struct
또는 해시를 사용하십시오. 코드의 특정 지점에서만 데이터를 사용하는 경우 해시도 적절합니다. 그러나 해당 데이터가 코드의 여러 경로를 통과하는 즉시 해시를 사용자 지정 class
또는 Struct
로 업그레이드하는 것을 두려워하지 마십시오. Aclass
는 데이터 모델의 모양을 더 잘 전달하고 결국 이를 적용할 수 있으므로 더 탄력적입니다. 여기서 잘못된 선택을 할 수 없으며 나중에 언제든지 데이터 구조를 업그레이드할 수 있습니다. Ruby는 그런 면에서 훌륭합니다.
Reference
이 문제에 관하여(Ruby의 OpenStruct에 대한 대안), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lorankloeze/alternative-for-rubys-openstruct-i72텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)