প্র: আমি কেন এই উত্তরটি বেছে নেব?
- আপনি যদি দ্রুততম গতি চান তবে এই উত্তরটি চয়ন করুন N নেট সক্ষম।
- আপনি যদি ক্লোনিংয়ের সত্যিই, সত্যই একটি সহজ পদ্ধতি চান তবে এই উত্তরটিকে উপেক্ষা করুন।
অন্য কথায়, যদি আপনার কোনও পারফরম্যান্স বাধা না থাকে তবে অন্য উত্তরের সাথে যান , যদি না আপনি ফিক্সিংয়ের প্রয়োজন হয় এবং আপনি এটি প্রোফাইলার দিয়ে প্রমাণ করতে পারবেন না ।
অন্যান্য পদ্ধতির তুলনায় 10x দ্রুত
গভীর ক্লোন সম্পাদন করার জন্য নিম্নলিখিত পদ্ধতিটি হ'ল:
- সিরিয়ালাইজেশন / ডেসারিয়ালাইজেশন জড়িত যে কোনও কিছু থেকে 10x দ্রুত;
- তাত্ত্বিক সর্বাধিক গতির কাছে খুব সুন্দর রঙিন। নেট সক্ষম is
এবং পদ্ধতি ...
চূড়ান্ত গতির জন্য, আপনি গভীর অনুলিপি করতে নেস্টেড মেম্বারওয়াই ক্লোন ব্যবহার করতে পারেন । এটি একটি মান কাঠামোর অনুলিপি করার মতো প্রায় একই গতি এবং (ক) প্রতিবিম্ব বা (খ) সিরিয়ালকরণ (এই পৃষ্ঠার অন্যান্য উত্তরে বর্ণিত) এর চেয়ে অনেক দ্রুত।
মনে রাখবেন যে আপনি যদি নেস্টেড মেম্বারওয়াই ক্লোনটি একটি গভীর অনুলিপিটির জন্য ব্যবহার করেন তবে আপনাকে ক্লাসে প্রতিটি নেস্টেড স্তরের জন্য ম্যানুয়ালি একটি শ্যালোকপি প্রয়োগ করতে হবে এবং একটি ডিপকপি যাতে একটি সম্পূর্ণ ক্লোন তৈরি করতে সমস্ত কথিত শ্যালোকিপি পদ্ধতি কল করে। এটি সহজ: মোট কয়েকটি লাইন, নীচের ডেমো কোডটি দেখুন।
এখানে কোডের আউটপুট 100,000 ক্লোনগুলির জন্য তুলনামূলক পারফরম্যান্স দেখায়:
- নেস্টেড স্ট্রাইভস স্ট্রাইক-তে নেস্টেড মেম্বারওয়াই ক্লোন এর জন্য 1.08 সেকেন্ড
- নেস্টেড মেম্বারওয়াই ক্লোনসের জন্য নেস্টেড ক্লাসে 4.77 সেকেন্ড
- সিরিয়ালাইজেশন / ডেসারিয়ালাইজেশনের জন্য 39.93 সেকেন্ড
কোনও কাঠামো অনুলিপি করার মতো ক্লাসে নেস্টেড মেম্বারসাই ক্লোন ব্যবহার করা এবং স্ট্রাক্ট অনুলিপি করা তাত্ত্বিক সর্বোচ্চ গতির কাছাকাছি খুব সুন্দর রঙিন। নেট সক্ষম।
Demo 1 of shallow and deep copy, using classes and MemberwiseClone:
Create Bob
Bob.Age=30, Bob.Purchase.Description=Lamborghini
Clone Bob >> BobsSon
Adjust BobsSon details
BobsSon.Age=2, BobsSon.Purchase.Description=Toy car
Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:
Bob.Age=30, Bob.Purchase.Description=Lamborghini
Elapsed time: 00:00:04.7795670,30000000
Demo 2 of shallow and deep copy, using structs and value copying:
Create Bob
Bob.Age=30, Bob.Purchase.Description=Lamborghini
Clone Bob >> BobsSon
Adjust BobsSon details:
BobsSon.Age=2, BobsSon.Purchase.Description=Toy car
Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:
Bob.Age=30, Bob.Purchase.Description=Lamborghini
Elapsed time: 00:00:01.0875454,30000000
Demo 3 of deep copy, using class and serialize/deserialize:
Elapsed time: 00:00:39.9339425,30000000
সদস্যপদার্থকপি ব্যবহার করে কীভাবে একটি অনুলিপি করা যায় তা বুঝতে, এখানে ডেমো প্রকল্পটি যা উপরের সময়গুলি তৈরি করতে ব্যবহৃত হয়েছিল:
// Nested MemberwiseClone example.
// Added to demo how to deep copy a reference class.
[Serializable] // Not required if using MemberwiseClone, only used for speed comparison using serialization.
public class Person
{
public Person(int age, string description)
{
this.Age = age;
this.Purchase.Description = description;
}
[Serializable] // Not required if using MemberwiseClone
public class PurchaseType
{
public string Description;
public PurchaseType ShallowCopy()
{
return (PurchaseType)this.MemberwiseClone();
}
}
public PurchaseType Purchase = new PurchaseType();
public int Age;
// Add this if using nested MemberwiseClone.
// This is a class, which is a reference type, so cloning is more difficult.
public Person ShallowCopy()
{
return (Person)this.MemberwiseClone();
}
// Add this if using nested MemberwiseClone.
// This is a class, which is a reference type, so cloning is more difficult.
public Person DeepCopy()
{
// Clone the root ...
Person other = (Person) this.MemberwiseClone();
// ... then clone the nested class.
other.Purchase = this.Purchase.ShallowCopy();
return other;
}
}
// Added to demo how to copy a value struct (this is easy - a deep copy happens by default)
public struct PersonStruct
{
public PersonStruct(int age, string description)
{
this.Age = age;
this.Purchase.Description = description;
}
public struct PurchaseType
{
public string Description;
}
public PurchaseType Purchase;
public int Age;
// This is a struct, which is a value type, so everything is a clone by default.
public PersonStruct ShallowCopy()
{
return (PersonStruct)this;
}
// This is a struct, which is a value type, so everything is a clone by default.
public PersonStruct DeepCopy()
{
return (PersonStruct)this;
}
}
// Added only for a speed comparison.
public class MyDeepCopy
{
public static T DeepCopy<T>(T obj)
{
object result = null;
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
result = (T)formatter.Deserialize(ms);
ms.Close();
}
return (T)result;
}
}
তারপরে, প্রধান থেকে ডেমো কল করুন:
void MyMain(string[] args)
{
{
Console.Write("Demo 1 of shallow and deep copy, using classes and MemberwiseCopy:\n");
var Bob = new Person(30, "Lamborghini");
Console.Write(" Create Bob\n");
Console.Write(" Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);
Console.Write(" Clone Bob >> BobsSon\n");
var BobsSon = Bob.DeepCopy();
Console.Write(" Adjust BobsSon details\n");
BobsSon.Age = 2;
BobsSon.Purchase.Description = "Toy car";
Console.Write(" BobsSon.Age={0}, BobsSon.Purchase.Description={1}\n", BobsSon.Age, BobsSon.Purchase.Description);
Console.Write(" Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:\n");
Console.Write(" Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);
Debug.Assert(Bob.Age == 30);
Debug.Assert(Bob.Purchase.Description == "Lamborghini");
var sw = new Stopwatch();
sw.Start();
int total = 0;
for (int i = 0; i < 100000; i++)
{
var n = Bob.DeepCopy();
total += n.Age;
}
Console.Write(" Elapsed time: {0},{1}\n\n", sw.Elapsed, total);
}
{
Console.Write("Demo 2 of shallow and deep copy, using structs:\n");
var Bob = new PersonStruct(30, "Lamborghini");
Console.Write(" Create Bob\n");
Console.Write(" Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);
Console.Write(" Clone Bob >> BobsSon\n");
var BobsSon = Bob.DeepCopy();
Console.Write(" Adjust BobsSon details:\n");
BobsSon.Age = 2;
BobsSon.Purchase.Description = "Toy car";
Console.Write(" BobsSon.Age={0}, BobsSon.Purchase.Description={1}\n", BobsSon.Age, BobsSon.Purchase.Description);
Console.Write(" Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:\n");
Console.Write(" Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);
Debug.Assert(Bob.Age == 30);
Debug.Assert(Bob.Purchase.Description == "Lamborghini");
var sw = new Stopwatch();
sw.Start();
int total = 0;
for (int i = 0; i < 100000; i++)
{
var n = Bob.DeepCopy();
total += n.Age;
}
Console.Write(" Elapsed time: {0},{1}\n\n", sw.Elapsed, total);
}
{
Console.Write("Demo 3 of deep copy, using class and serialize/deserialize:\n");
int total = 0;
var sw = new Stopwatch();
sw.Start();
var Bob = new Person(30, "Lamborghini");
for (int i = 0; i < 100000; i++)
{
var BobsSon = MyDeepCopy.DeepCopy<Person>(Bob);
total += BobsSon.Age;
}
Console.Write(" Elapsed time: {0},{1}\n", sw.Elapsed, total);
}
Console.ReadKey();
}
আবার, মনে রাখবেন যে আপনি যদি নেস্টেড মেম্বারওয়াই ক্লোনটি একটি গভীর অনুলিপিটির জন্য ব্যবহার করেন তবে আপনাকে ক্লাসে প্রতিটি নেস্টেড স্তরের জন্য ম্যানুয়ালি একটি শ্যালোকপি প্রয়োগ করতে হবে এবং একটি ডিপকপি যাতে একটি সম্পূর্ণ ক্লোন তৈরি করতে সমস্ত কথিত শ্যালোকপি পদ্ধতি বলে থাকে। এটি সহজ: মোট কয়েকটি লাইন, উপরের ডেমো কোডটি দেখুন।
মান প্রকারের বনাম রেফারেন্স প্রকার
মনে রাখবেন যে যখন কোনও বস্তুর ক্লোনিংয়ের বিষয়টি আসে তখন " স্ট্রাক্ট " এবং " শ্রেণি " এর মধ্যে একটি বড় পার্থক্য থাকে :
- আপনার যদি " স্ট্রাক্ট " থাকে তবে এটি একটি মান ধরণের যা আপনি কেবল এটি অনুলিপি করতে পারেন, এবং বিষয়বস্তুগুলি ক্লোন করা হবে (তবে আপনি যদি এই পোস্টে কৌশলগুলি ব্যবহার না করেন তবে এটি কেবল অগভীর ক্লোন তৈরি করবে)।
- আপনার যদি " শ্রেণি " থাকে তবে এটি একটি রেফারেন্স টাইপ , তাই আপনি যদি এটি অনুলিপি করেন তবে আপনি যা করছেন তা পয়েন্টারটি অনুলিপি করছে। সত্যিকারের ক্লোন তৈরি করতে আপনাকে আরও সৃজনশীল হতে হবে এবং মান ধরণের এবং রেফারেন্সের ধরণের মধ্যে পার্থক্য ব্যবহার করতে হবে যা মেমরিতে আসল বস্তুর অন্য অনুলিপি তৈরি করে।
মান ধরণের এবং রেফারেন্সের ধরণের মধ্যে পার্থক্য দেখুন ।
ডিবাগিংয়ে সহায়তা করার জন্য চেকসামগুলি
- অবৈধভাবে ভুলভাবে ক্লোনিং করা খুব কঠিন-থেকে-পিন-ডাউন বাগগুলিতে নিয়ে যেতে পারে। প্রোডাকশন কোডে, আমি চেকসামটি ডাবল চেক করার জন্য বস্তুটি সঠিকভাবে ক্লোন করা হয়েছে, এবং এটির অন্য কোনও রেফারেন্স দ্বারা দূষিত হয়নি তা প্রয়োগ করার প্রবণতা পোষণ করি। এই চেকসামটি রিলিজ মোডে স্যুইচ অফ করা যেতে পারে।
- আমি এই পদ্ধতিটি বেশ দরকারী বলে মনে করি: প্রায়শই আপনি কেবলমাত্র সামগ্রীর অংশটিই ক্লোন করতে চান।
অন্যান্য অনেক থ্রেড থেকে অনেক থ্রেড decoupling জন্য সত্যই দরকারী
এই কোডটির জন্য একটি দুর্দান্ত ব্যবহারের ক্ষেত্র হ'ল উত্পাদক / গ্রাহক নিদর্শন বাস্তবায়নের জন্য নেস্টেড শ্রেণীর ক্লোনগুলি খাওয়ানো বা একটি সারিতে স্ট্রাকচার।
- আমাদের কাছে একটি (বা আরও) থ্রেড থাকতে পারে তারা নিজের মালিকানাধীন একটি ক্লাসটি পরিবর্তন করতে পারে, তারপরে এই শ্রেণীর একটি সম্পূর্ণ অনুলিপি এ তে ঠেলে দেয়
ConcurrentQueue
।
- আমাদের তখন এই ক্লাসগুলির অনুলিপিগুলি টানতে এবং তাদের সাথে ডিল করার জন্য একটি (বা আরও) থ্রেড রয়েছে।
এটি অনুশীলনে চূড়ান্তভাবে কাজ করে এবং আমাদের এক বা একাধিক থ্রেড (গ্রাহক) থেকে বহু থ্রেড (প্রযোজক) ডিকুয়াল করার অনুমতি দেয়।
এবং এই পদ্ধতিটি অন্ধভাবে দ্রুতও: আমরা যদি নেস্টেড স্ট্রিং ব্যবহার করি তবে এটি নেস্টেড ক্লাসগুলিকে সিরিয়ালাইজেশন / ডিসাইরিয়ালাইজড করার চেয়ে 35x দ্রুত এবং আমাদের মেশিনে উপলব্ধ সমস্ত থ্রেডের সুবিধা নিতে দেয়।
হালনাগাদ
স্পষ্টতই, এক্সপ্রেসপ্যাপার উপরের মতো হ্যান্ড কোডিংয়ের চেয়ে দ্রুত, যদি দ্রুত না হয়। আমাকে দেখতে হবে তারা কীভাবে একজন প্রোফাইকারের সাথে তুলনা করে।