ප්රශ්නය - මම මෙම පිළිතුර තෝරා ගන්නේ ඇයි?
- ඔබට වේගවත්ම වේගය අවශ්ය නම් මෙම පිළිතුර තෝරන්න .NET හැකියාව ඇත.
- ඔබට ඉතා පහසුවෙන් ක්ලෝන කිරීමේ ක්රමයක් අවශ්ය නම් මෙම පිළිතුර නොසලකා හරින්න.
වෙනත් වචන වලින් කිවහොත්, ඔබට නිවැරදි කිරීමට අවශ්ය කාර්ය සාධන බාධකයක් නොමැති නම් වෙනත් පිළිතුරක් සමඟ යන්න, ඔබට එය පැතිකඩකින් ඔප්පු කළ හැකිය .
වෙනත් ක්රමවලට වඩා 10x වේගවත්
ගැඹුරු ක්ලෝනයක් සිදු කිරීමේ පහත ක්රමය නම්:
- අනුක්රමිකකරණය / ආශ්රිතකරණයට සම්බන්ධ ඕනෑම දෙයකට වඩා 10x වේගවත්;
- න්යායාත්මක උපරිම වේගයට ආසන්නව ඉතා අලංකාරයි .නෙට් හැකියාව ඇත.
ක්රමය ...
අවසාන වේගය සඳහා, ගැඹුරු පිටපතක් කිරීමට ඔබට නෙස්ටඩ් සාමාජික වයිස් ක්ලෝන් භාවිතා කළ හැකිය . එය අගය ව්යුහයක් පිටපත් කිරීමට සමාන වේගයකින් යුක්ත වන අතර (අ) පරාවර්තනය හෝ (ආ) අනුක්රමිකකරණයට වඩා වේගවත් වේ (මෙම පිටුවේ වෙනත් පිළිතුරු වල විස්තර කර ඇති පරිදි).
ගැඹුරු පිටපතක් සඳහා ඔබ නෙස්ටඩ් සාමාජික ක්ලෝන් භාවිතා කරන්නේ නම් , ඔබ පන්තියේ සෑම කැදැලි මට්ටමක් සඳහාම නොගැඹුරු කොපියක් අතින් ක්රියාත්මක කළ යුතු අතර සම්පූර්ණ ක්ලෝනයක් නිර්මාණය කිරීම සඳහා කියූ ෂැලෝකොපි ක්රම සියල්ලම හඳුන්වන ඩීප්කොපි ය. මෙය සරලයි: සම්පූර්ණ පේළි කිහිපයක් පමණි, පහත නිරූපණ කේතය බලන්න.
ක්ලෝන 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
MemberwiseCopy භාවිතයෙන් ගැඹුරු පිටපතක් කරන්නේ කෙසේද යන්න තේරුම් ගැනීමට, ඉහත වේලාවන් උත්පාදනය කිරීම සඳහා භාවිතා කළ ආදර්ශන ව්යාපෘතිය මෙන්න:
// 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();
}
නැවතත්, ගැඹුරු පිටපතක් සඳහා ඔබ නෙස්ටඩ් සාමාජික ක්ලෝන් භාවිතා කරන්නේ නම් , ඔබ පන්තියේ සෑම කැදැල්ලකටම නොගැඹුරු කොපියක් අතින් ක්රියාත්මක කළ යුතු අතර සම්පූර්ණ ක්ලෝනයක් නිර්මාණය කිරීම සඳහා කියූ ෂැලෝකොපි ක්රම සියල්ලම හඳුන්වන ඩීප්කොපි ය. මෙය සරලයි: සම්පූර්ණ පේළි කිහිපයක් පමණි, ඉහත ආදර්ශන කේතය බලන්න.
අගය වර්ග එදිරිව යොමු සටහන් වර්ග
වස්තුවක් ක්ලෝන කිරීමේදී " struct " සහ " class " අතර විශාල වෙනසක් ඇති බව සලකන්න :
- ඔබට " struct " තිබේ නම්, එය අගය වර්ගයක් බැවින් ඔබට එය පිටපත් කළ හැකිය, එවිට අන්තර්ගතය ක්ලෝන කරනු ලැබේ (නමුත් එය නොගැඹුරු ක්ලෝනයක් සාදනුයේ ඔබ මෙම තනතුරේ ශිල්පීය ක්රම භාවිතා නොකරන්නේ නම් පමණි).
- ඔබට " පංතියක් " තිබේ නම්, එය විමර්ශන වර්ගයකි , එබැවින් ඔබ එය පිටපත් කරන්නේ නම්, ඔබ කරන්නේ ඒ සඳහා දර්ශකය පිටපත් කිරීමයි. සත්ය ක්ලෝනයක් නිර්මාණය කිරීම සඳහා, ඔබ වඩාත් නිර්මාණශීලී විය යුතු අතර, මතක වර්ගයේ මුල් වස්තුවේ තවත් පිටපතක් නිර්මාණය කරන අගය වර්ග සහ යොමු වර්ග අතර වෙනස්කම් භාවිතා කරන්න .
අගය වර්ග සහ යොමු වර්ග අතර වෙනස්කම් බලන්න .
නිදොස්කරණය සඳහා සහාය වන චෙක්සම්
- වස්තූන් වැරදියට ක්ලෝන කිරීම ඉතා අපහසු-සිට-පහළට-දෝෂ වලට තුඩු දිය හැකිය. නිෂ්පාදන කේතයේ දී, වස්තුව නිසියාකාරව ක්ලෝන කර ඇත්දැයි දෙවරක් පරීක්ෂා කිරීම සඳහා චෙක්සමයක් ක්රියාත්මක කිරීමට මම නැඹුරු වෙමි. මෙම චෙක්සමය මුදා හැරීමේ ආකාරයෙන් ක්රියා විරහිත කළ හැකිය.
- මෙම ක්රමය බෙහෙවින් ප්රයෝජනවත් බව මට පෙනේ: බොහෝ විට, ඔබට අවශ්ය වන්නේ වස්තුවේ කොටස් පමණක් ක්ලෝන කිරීමට මිස සමස්ත දේම නොවේ.
වෙනත් බොහෝ නූල් වලින් බොහෝ නූල් විසන්ධි කිරීමට සැබවින්ම ප්රයෝජනවත් වේ
මෙම කේතය සඳහා එක් විශිෂ්ට භාවිතයක් වන්නේ නිෂ්පාදකයා / පාරිභෝගික රටාව ක්රියාත්මක කිරීම සඳහා කැදැලි පන්තියක හෝ ව්යුහයක් පෝලිම්වලට පෝෂණය කිරීමයි.
- අපට ඔවුන් සතුව ඇති පන්තියක් වෙනස් කරමින් නූල් එකක් (හෝ වැඩි ගණනක්) තිබිය හැකි අතර පසුව මෙම පන්තියේ සම්පූර්ණ පිටපතක් a
ConcurrentQueue
.
- මෙම පංතිවල පිටපත් ඉවතට ගෙන ඒවා සමඟ ගනුදෙනු කිරීමේදී අපට නූල් එකක් (හෝ වැඩි ගණනක්) ඇත.
මෙය ප්රායෝගිකව ඉතා හොඳින් ක්රියාත්මක වන අතර, නූල් එකක් හෝ වැඩි ගණනකින් (පාරිභෝගිකයින්) බොහෝ නූල් (නිෂ්පාදකයන්) විසන්ධි කිරීමට අපට ඉඩ දෙයි.
මෙම ක්රමය ද අන්ධ ලෙස වේගවත් ය: අප කැදැලි ව්යුහයන් භාවිතා කරන්නේ නම්, එය කැදැලි පන්ති අනුක්රමිකකරණයට / අවපීඩනයට වඩා 35x වේගවත් වන අතර යන්ත්රයේ ඇති සියලුම නූල් වලින් ප්රයෝජන ගැනීමට අපට ඉඩ සලසයි.
යාවත්කාලීන කරන්න
පෙනෙන ආකාරයට, එක්ස්ප්රස්මැපර් ඉහත වැනි අත් කේතීකරණයට වඩා වේගවත්, වේගවත් නොවේ නම්. ඔවුන් පැතිකඩක් සමඟ සංසන්දනය කරන්නේ කෙසේදැයි මට දැකීමට සිදුවනු ඇත.