মাইক্রোসফ্ট দ্বারা পরিত্যক্ত ফ্রেমওয়ার্ক ব্যবহারকারীরা এখানে আমাদের জন্য অন্য সংস্করণ। এটা তোলে যত দ্রুত 4 বার হয় Array.Clear
এবং দ্রুত তুলনায় প্যানোগুলি Theof এর সমাধান এবং এরিক জে এর এবং Petar পেট্রোভ এর সমান্তরাল এক দুই বার ফাস্ট বৃহৎ অ্যারে হিসাবে -।
প্রথমে আমি আপনাকে ফাংশনের পূর্বপুরুষকে উপস্থাপন করতে চাই, কারণ এটি কোডটি বোঝা সহজ করে তোলে। প্যানোস থিওফের কোডের সাথে সামঞ্জস্যপূর্ণ পারফরম্যান্স-ভিত্তিক এবং এমন কিছু জিনিসের জন্য যা ইতিমধ্যে যথেষ্ট হতে পারে:
public static void Fill<T> (T[] array, int count, T value, int threshold = 32)
{
if (threshold <= 0)
throw new ArgumentException("threshold");
int current_size = 0, keep_looping_up_to = Math.Min(count, threshold);
while (current_size < keep_looping_up_to)
array[current_size++] = value;
for (int at_least_half = (count + 1) >> 1; current_size < at_least_half; current_size <<= 1)
Array.Copy(array, 0, array, current_size, current_size);
Array.Copy(array, 0, array, current_size, count - current_size);
}
আপনি দেখতে পাচ্ছেন, এটি ইতিমধ্যে-প্রাথমিক অংশটি বারবার দ্বিগুণ করার উপর ভিত্তি করে। এটি সহজ এবং দক্ষ, তবে এটি আধুনিক স্মৃতি আর্কিটেকচারের পুরোপুরি চলে। সুতরাং একটি সংস্করণ জন্মগ্রহণ করেছে যা কেবলমাত্র ক্যাশে-বান্ধব বীজ ব্লক তৈরি করতে দ্বিগুণ ব্যবহার করে, যা লক্ষ্যমাত্রার পরে পুনরাবৃত্তভাবে বিস্ফোরিত হয়:
const int ARRAY_COPY_THRESHOLD = 32; // 16 ... 64 work equally well for all tested constellations
const int L1_CACHE_SIZE = 1 << 15;
public static void Fill<T> (T[] array, int count, T value, int element_size)
{
int current_size = 0, keep_looping_up_to = Math.Min(count, ARRAY_COPY_THRESHOLD);
while (current_size < keep_looping_up_to)
array[current_size++] = value;
int block_size = L1_CACHE_SIZE / element_size / 2;
int keep_doubling_up_to = Math.Min(block_size, count >> 1);
for ( ; current_size < keep_doubling_up_to; current_size <<= 1)
Array.Copy(array, 0, array, current_size, current_size);
for (int enough = count - block_size; current_size < enough; current_size += block_size)
Array.Copy(array, 0, array, current_size, block_size);
Array.Copy(array, 0, array, current_size, count - current_size);
}
দ্রষ্টব্য: (count + 1) >> 1
দ্বিগুণ লুপের সীমা হিসাবে পূর্ববর্তী কোডের প্রয়োজনীয়তাটি নিশ্চিত করতে চূড়ান্ত অনুলিপি অপারেশনটিতে যে সমস্ত বাকী রয়েছে তা coverাকতে পর্যাপ্ত পরিমাণে চোর রয়েছে। এটির count >> 1
পরিবর্তে যদি ব্যবহার করা হয় তবে বিজোড় সংখ্যাগুলির ক্ষেত্রে এটি হবে না । বর্তমান সংস্করণের জন্য এটি কোনও তাত্পর্যপূর্ণ নয় যেহেতু রৈখিক অনুলিপি লুপ যে কোনও স্লোকে তুলবে।
একটি অ্যারে ঘরের আকার অবশ্যই প্যারামিটার হিসাবে পাস করতে হবে কারণ - মাইন্ড বগলস - জেনেরিকগুলি ব্যবহার করতে অনুমতি দেয় sizeof
না যদি না তারা সীমাবদ্ধতা ( unmanaged
) ব্যবহার করে যা ভবিষ্যতে উপলব্ধ নাও হতে পারে। ভুল অনুমানগুলি কোনও বড় বিষয় নয় তবে নিম্নলিখিত কারণগুলির জন্য মানটি সঠিক হলে কর্মক্ষমতা সর্বোত্তম:
উপাদানের আকারকে অবমূল্যায়ন করার ফলে L1 ক্যাশের অর্ধেকেরও বেশি আকারের ব্লক মাপগুলি বাড়ে, ফলে অনুলিপি উত্সের ডেটা L1 থেকে উচ্ছেদ হওয়ার সম্ভাবনা বাড়ায় এবং ধীর ক্যাশে স্তর থেকে পুনরায় আনতে হবে।
সিপিইউর এল 1 ক্যাশে আন্ডার-ইউজিলিমেটেড উপাদান আকারের পর্যালোচনা করা, মানে লিনিয়ার ব্লক কপি লুপটি সর্বোত্তম ব্যবহারের চেয়ে প্রায়শই কার্যকর হয় exec সুতরাং, কঠোরভাবে প্রয়োজনের তুলনায় স্থির লুপ / কল ওভারহেডের বেশি।
এখানে আমার কোড Array.Clear
এবং এর আগে উল্লিখিত অন্যান্য তিনটি সমাধানের বিপরীতমুখী একটি মানদণ্ড রয়েছে । সময়গুলি Int32[]
প্রদত্ত আকারের পূর্ণসংখ্যার অ্যারে ( ) পূরণ করার জন্য । ক্যাশে ভিজিরি ইত্যাদির ফলে হ'ল প্রকরণ হ্রাস করার জন্য প্রতিটি পরীক্ষা দু'বার কার্যকর করা হয়েছিল, পিছনে থেকে পিছনে, এবং দ্বিতীয় নির্বাহের জন্য সময় নেওয়া হয়েছিল।
array size Array.Clear Eric J. Panos Theof Petar Petrov Darth Gizka
-------------------------------------------------------------------------------
1000: 0,7 µs 0,2 µs 0,2 µs 6,8 µs 0,2 µs
10000: 8,0 µs 1,4 µs 1,2 µs 7,8 µs 0,9 µs
100000: 72,4 µs 12,4 µs 8,2 µs 33,6 µs 7,5 µs
1000000: 652,9 µs 135,8 µs 101,6 µs 197,7 µs 71,6 µs
10000000: 7182,6 µs 4174,9 µs 5193,3 µs 3691,5 µs 1658,1 µs
100000000: 67142,3 µs 44853,3 µs 51372,5 µs 35195,5 µs 16585,1 µs
যদি এই কোডটির পারফরম্যান্স পর্যাপ্ত না হয় তবে একটি প্রতিশ্রুতিবদ্ধ অ্যাভিনিউ লিনিয়ার কপি লুপের সমান্তরাল করা হবে (একই উত্সের ব্লকটি ব্যবহার করে সমস্ত থ্রেড সহ) বা আমাদের ভাল পুরানো বন্ধু পি / ইনভোকে।
দ্রষ্টব্য: ব্লকগুলি সাফ করা এবং পূরণ করা সাধারণত রানটাইম রুটিন দ্বারা সম্পন্ন হয় যা শাখাটি এমএমএক্স / এসএসই নির্দেশাবলী এবং হোয়াট নোট ব্যবহার করে অত্যন্ত বিশেষ কোডগুলিতে শাখা করে, সুতরাং যে কোনও শালীন পরিবেশে কোনও ব্যক্তি কেবল স্বতন্ত্র নৈতিক সমতুল্য কল করবে std::memset
এবং পেশাদার কর্মক্ষমতা স্তরের বিষয়ে নিশ্চিত হবে। আইওডাব্লু, অধিকার অনুসারে লাইব্রেরির ফাংশনটি Array.Clear
আমাদের সমস্ত হাত-ঘূর্ণিত সংস্করণ ধূলিকণায় ফেলে রাখা উচিত। এটি অন্য উপায়ে যে ঘটনাটি ঘটে তা প্রকৃতপক্ষে দূর্বার বিষয়গুলির থেকে কতটা দূরে shows সবার Fill<>
প্রথমে নিজের রোল করার জন্য একই কারণ এটি এখনও কেবলমাত্র কোর এবং স্ট্যান্ডার্ডে রয়েছে তবে ফ্রেমওয়ার্কে নয়। নেট প্রায় প্রায় বিশ বছর ধরে হয়েছে এবং আমাদের এখনও বেসিক স্টাফগুলির জন্য বাম এবং ডান পি / ইনভোক করতে হবে বা আমাদের নিজস্ব রোল করতে হবে ...