সাধারণভাবে, কোনও স্ট্রাক্টের তুলনায় ওপেনস্ট্রাক্ট ব্যবহারের সুবিধা এবং অসুবিধাগুলি কী কী? এগুলির প্রতিটি কী ধরণের সাধারণ ব্যবহারের সাথে খাপ খায়?
সাধারণভাবে, কোনও স্ট্রাক্টের তুলনায় ওপেনস্ট্রাক্ট ব্যবহারের সুবিধা এবং অসুবিধাগুলি কী কী? এগুলির প্রতিটি কী ধরণের সাধারণ ব্যবহারের সাথে খাপ খায়?
উত্তর:
একটি দিয়ে OpenStruct
, আপনি নির্বিচারে বৈশিষ্ট্য তৈরি করতে পারেন। একটি Struct
অন্যদিকে, যখন আপনি এটি তৈরি তার গুণাবলী সংজ্ঞায়িত থাকতে হবে। একজনের অপরটির পছন্দ মূলত ভিত্তিক হওয়া উচিত আপনার পরবর্তীকালে গুণাবলী যুক্ত করতে সক্ষম হওয়া দরকার কিনা।
এগুলি সম্পর্কে চিন্তাভাবনা করার উপায়টি হ্যাশগুলির একদিকে এবং অন্যদিকে শ্রেণীর মধ্যবর্তী বর্ণালীটির মাঝের ক্ষেত্র হিসাবে। তারা ডেটার মধ্যে একটি তুলনায় আরও দৃ concrete় সম্পর্ক বোঝায় Hash
, তবে তাদের ক্লাসের মতো উদাহরণ পদ্ধতি নেই। একটি ফাংশনের জন্য বিকল্পগুলির একটি গোছা, উদাহরণস্বরূপ, একটি হ্যাশটি বোঝায়; তারা কেবল আলগাভাবে সম্পর্কিত। একটি ক্রিয়াকলাপের জন্য প্রয়োজনীয় একটি নাম, ইমেল এবং ফোন নম্বর একটি Struct
বা একসাথে প্যাকেজ করা যেতে পারে OpenStruct
। যদি সেই নাম, ইমেল এবং ফোন নম্বরটির জন্য "প্রথম সর্বশেষ" এবং "শেষ, প্রথম" উভয় ফর্ম্যাটে নাম সরবরাহ করতে প্রয়োজন হয়, তবে আপনার এটি পরিচালনা করার জন্য একটি শ্রেণি তৈরি করা উচিত।
class Point < Struct.new(:x, :y); methods here; end
Point = Struct.new(:x, :y) { methods here }
। ( উত্স ) অবশ্যই, { ... }
সেখানে একটি বহু-লাইন ব্লক ( do ... end
) লেখা যেতে পারে এবং আমি মনে করি, এটি পছন্দসই উপায়।
অন্যান্য মানদণ্ড:
require 'benchmark'
require 'ostruct'
REP = 100000
User = Struct.new(:name, :age)
USER = "User".freeze
AGE = 21
HASH = {:name => USER, :age => AGE}.freeze
Benchmark.bm 20 do |x|
x.report 'OpenStruct slow' do
REP.times do |index|
OpenStruct.new(:name => "User", :age => 21)
end
end
x.report 'OpenStruct fast' do
REP.times do |index|
OpenStruct.new(HASH)
end
end
x.report 'Struct slow' do
REP.times do |index|
User.new("User", 21)
end
end
x.report 'Struct fast' do
REP.times do |index|
User.new(USER, AGE)
end
end
end
অধৈর্য যে বেঞ্চমার্কের ফলাফলগুলি নিজেরাই না চালিয়ে সে সম্পর্কে ধারণা পেতে চায় তাদের জন্য উপরের কোডটির আউটপুট (এমবি প্রো 2.4GHz i7 এ)
user system total real
OpenStruct slow 4.430000 0.250000 4.680000 ( 4.683851)
OpenStruct fast 4.380000 0.270000 4.650000 ( 4.649809)
Struct slow 0.090000 0.000000 0.090000 ( 0.094136)
Struct fast 0.080000 0.000000 0.080000 ( 0.078940)
হালনাগাদ:
রুবি ২.৪.১ হিসাবে ওপেনস্ট্রাক্ট এবং স্ট্রাক্ট গতিতে অনেক বেশি কাছাকাছি। Https://stackoverflow.com/a/43987844/128421 দেখুন
পূর্বে:
সম্পূর্ণতার জন্য: স্ট্রাক্ট বনাম ক্লাস বনাম হ্যাশ বনাম ওপেনস্ট্রাক্ট
রুবি ১.৯.২, (৪ টি কোরের x86_64 এর মধ্যে 1 টি, 8 জিবি র্যাম) তে একই জাতীয় কোড বার্টলো হিসাবে চালানো [কলামগুলি সারিবদ্ধ করার জন্য সারণী সম্পাদিত]:
1 টি মিও স্ট্রাক্ট তৈরি করছে: 1.43 সেকেন্ড, 219 এমবি / 90 এমবি (পুণ্য / পুনরায়) 1 টি মিও ক্লাসের উদাহরণ তৈরি করছে: 1.43 সেকেন্ড, 219 এমবি / 90 এমবি (পুণ্য / পুনরায়) 1 টি মিও হ্যাশ তৈরি করছে: 4.46 সেকেন্ড, 493 এমবি / 364 এমবি (গুণ / পুনরায়) 1 মিও ওপেনস্ট্রাক্টস তৈরি করা হচ্ছে: 415.13 সেকেন্ড, 2464 এমবি / 2.3 জিবি (গুণ / পুনরায়) # হ্যাশগুলির তুলনায় # ~ 100x কম 100 কে ওপেনস্ট্রাক্টস তৈরি করা হচ্ছে: 10.96 সেকেন্ড, 369 এমবি / 242 এমবি (গুণ / পুনরায়)
ওপেনস্ট্রাক্টগুলি স্লুওউও এবং মেমরি নিবিড় , এবং বড় ডেটা সেটগুলির জন্য ভাল স্কেল করে না
1 মায়ো OpenStructs তৈরি করছে ~ 100x তুলনায় ধীর 1 মায়ো তৈরি হ্যাশ ।
start = Time.now
collection = (1..10**6).collect do |i|
{:name => "User" , :age => 21}
end; 1
stop = Time.now
puts "#{stop - start} seconds elapsed"
দুজনের ব্যবহারের ক্ষেত্রে বিষয়টি বেশ আলাদা।
আপনি রুবি ১.৯ এর স্ট্রাক্ট ক্লাসটি struct
সি এর ঘোষণার সমতুল্য হিসাবে ভাবতে পারেন রুবি ইন Struct.new
আর্গুমেন্ট হিসাবে ক্ষেত্রের নামগুলির একটি সেট নেয় এবং একটি নতুন ক্লাস দেয় returns একইভাবে, সি তে, একটি struct
ঘোষণাপত্র ক্ষেত্রগুলির একটি সেট নেয় এবং প্রোগ্রামারকে নতুন জটিল ধরণের ব্যবহার করতে দেয় যেমন তার কোনও বিল্ট-ইন টাইপ থাকে।
রুবি:
Newtype = Struct.new(:data1, :data2)
n = Newtype.new
সি:
typedef struct {
int data1;
char data2;
} newtype;
newtype n;
ওপেনস্ট্রাক্ট ক্লাসটি সি এর সাথে একটি বেনামি স্ট্রাক্ট ঘোষণার সাথে তুলনা করা যেতে পারে যা প্রোগ্রামারকে একটি জটিল ধরণের উদাহরণ তৈরি করতে দেয় ।
রুবি:
o = OpenStruct.new(data1: 0, data2: 0)
o.data1 = 1
o.data2 = 2
সি:
struct {
int data1;
char data2;
} o;
o.data1 = 1;
o.data2 = 2;
এখানে কিছু সাধারণ ব্যবহারের মামলা রয়েছে।
ওপেনস্ট্রাক্টস হ্যাশগুলি সহজেই এক-অফ-অবজেক্টগুলিতে রূপান্তর করতে ব্যবহার করা যেতে পারে যা সমস্ত হ্যাশ কীগুলিতে সাড়া দেয়।
h = { a: 1, b: 2 }
o = OpenStruct.new(h)
o.a = 1
o.b = 2
শর্টহ্যান্ড শ্রেণীর সংজ্ঞাগুলির জন্য স্ট্রোকগুলি কার্যকর হতে পারে।
class MyClass < Struct.new(:a,:b,:c)
end
m = MyClass.new
m.a = 1
ওপেনস্ট্রাক্টস উল্লেখযোগ্যভাবে আরও মেমরি ব্যবহার করে এবং স্ট্রাক্টের তুলনায় ধীর পারফর্মার।
require 'ostruct'
collection = (1..100000).collect do |index|
OpenStruct.new(:name => "User", :age => 21)
end
আমার সিস্টেমে নিম্নলিখিত কোডটি 14 সেকেন্ডে কার্যকর করা হয়েছিল এবং 1.5 গিগাবাইট মেমরি গ্রহণ করেছে। আপনার মাইলেজ বিভিন্ন হতে পারে:
User = Struct.new(:name, :age)
collection = (1..100000).collect do |index|
User.new("User",21)
end
এটি প্রায় তাত্ক্ষণিকভাবে শেষ হয়েছে এবং 26.6 এমবি মেমরি গ্রহণ করেছে med
Struct
:
>> s = Struct.new(:a, :b).new(1, 2)
=> #<struct a=1, b=2>
>> s.a
=> 1
>> s.b
=> 2
>> s.c
NoMethodError: undefined method `c` for #<struct a=1, b=2>
OpenStruct
:
>> require 'ostruct'
=> true
>> os = OpenStruct.new(a: 1, b: 2)
=> #<OpenStruct a=1, b=2>
>> os.a
=> 1
>> os.b
=> 2
>> os.c
=> nil
নতুন পদ্ধতির বিষয়ে API এ দেখুন। সেখানে অনেক পার্থক্য পাওয়া যায়।
ব্যক্তিগতভাবে, আমি বেশ ওপেনস্ট্রাক্টকে পছন্দ করি, কারণ আমার আগে অবজেক্টের কাঠামো সংজ্ঞায়িত করতে হবে না, এবং আমার ইচ্ছে মতো স্টাফ যুক্ত করতে হবে। আমি অনুমান করি যে এটির মূল (ডিস) সুবিধা হবে?
@ রবার্ট কোড ব্যবহার করে আমি হাশি :: ম্যাসকে মাপদণ্ডের আইটেমটিতে যুক্ত করেছি এবং এই ফলাফলটি পেয়েছি:
user system total real
Hashie::Mash slow 3.600000 0.000000 3.600000 ( 3.755142)
Hashie::Mash fast 3.000000 0.000000 3.000000 ( 3.318067)
OpenStruct slow 11.200000 0.010000 11.210000 ( 12.095004)
OpenStruct fast 10.900000 0.000000 10.900000 ( 12.669553)
Struct slow 0.370000 0.000000 0.370000 ( 0.470550)
Struct fast 0.140000 0.000000 0.140000 ( 0.145161)
আসলে প্রশ্নের উত্তর নয়, তবে আপনি যদি পারফরম্যান্সের বিষয়ে চিন্তা করেন তবে খুব গুরুত্বপূর্ণ বিবেচনা । দয়া করে লক্ষ্য করুন যে আপনি যখনই কোনও OpenStruct
অপারেশন তৈরি করবেন তখন পদ্ধতি ক্যাশে সাফ করে, যার অর্থ আপনার অ্যাপ্লিকেশনটি ধীর গতিতে কাজ করবে। মন্দতা বা না হওয়া OpenStruct
কেবল এটি নিজের দ্বারা কীভাবে কাজ করে তা নয়, তবে এগুলি ব্যবহার করে যে সমস্ত প্রভাবগুলি পুরো প্রয়োগটিতে আসে: https://github.com/charliesome/charlie.bz/blob/master/posts/things-that -clear-rubys-method-cache.md # openstructs