আপনার পছন্দসই প্রোগ্রামিং ভাষায় 1 থেকে 2,000,000 পর্যন্ত সমস্ত সংখ্যা যোগ করার চেষ্টা করেছেন? ফলাফলটি ম্যানুয়ালি গণনা করা সহজ: 2,000,001,000,000, যা স্বাক্ষরবিহীন 32 বিট পূর্ণসংখ্যার সর্বোচ্চ মানের চেয়ে 900 গুণ বেশি।
সি # প্রিন্ট আউট -1453759936
- একটি নেতিবাচক মান! এবং আমার ধারণা জাভাও তাই করে।
এর অর্থ এমন কিছু সাধারণ প্রোগ্রামিং ল্যাঙ্গুয়েজ রয়েছে যা ডিফল্টরূপে অংকিত ওভারফ্লো উপেক্ষা করে (সি # তে, এটি পরিবর্তনের জন্য লুকানো বিকল্প রয়েছে)। এটি এমন একটি আচরণ যা আমার কাছে খুব ঝুঁকিপূর্ণ বলে মনে হচ্ছে, এবং এরিয়েন 5 এর ক্র্যাশটি এতটা প্রবাহের কারণে হয়নি?
সুতরাং: এই জাতীয় বিপজ্জনক আচরণের পিছনে নকশার সিদ্ধান্তগুলি কী কী?
সম্পাদনা:
এই প্রশ্নের প্রথম উত্তরগুলি চেক করার অতিরিক্ত খরচ প্রকাশ করে। এই অনুমানটি পরীক্ষা করতে আসুন একটি সংক্ষিপ্ত সি # প্রোগ্রাম কার্যকর করুন:
Stopwatch watch = Stopwatch.StartNew();
checked
{
for (int i = 0; i < 200000; i++)
{
int sum = 0;
for (int j = 1; j < 50000; j++)
{
sum += j;
}
}
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalMilliseconds);
আমার মেশিনে, পরীক্ষিত সংস্করণটি 11015 মিমি লাগে, যখন চেক করা সংস্করণটি 4125 মিমি লাগে। অর্থাত্ চেকিং পদক্ষেপগুলি সংখ্যার যোগ করতে প্রায় দ্বিগুণ সময় নেয় (মূল সময়ের সাথে মোট 3 বার)। তবে 10,000,000,000 পুনরাবৃত্তি সহ, একটি চেকের সময় নেওয়া এখনও 1 ন্যানোসেকেন্ডের চেয়ে কম। এমন পরিস্থিতি থাকতে পারে যেখানে এটি গুরুত্বপূর্ণ, তবে বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য, এটি গুরুত্বপূর্ণ নয়।
সম্পাদনা 2:
আমি আমাদের সার্ভার অ্যাপ্লিকেশনটি পুনরায় সংকলিত করেছি (একটি উইন্ডোজ পরিষেবাটি বেশ কয়েকটি সেন্সর থেকে প্রাপ্ত তথ্য বিশ্লেষণকারী, বেশ কিছু সংখ্যক ক্রંચিং জড়িত) জড়িত /p:CheckForOverflowUnderflow="false"
প্যারামিটার দিয়ে (সাধারণত, আমি ওভারফ্লো চেক অন স্যুইচ করে) এবং এটি একটি ডিভাইসে স্থাপন করি। নাগিওস পর্যবেক্ষণ দেখায় যে গড় সিপিইউ লোড 17% এ দাঁড়িয়েছে।
এর অর্থ হল যে উপরে বর্ণিত উদাহরণটিতে প্রদর্শিত পারফরম্যান্স হিটটি আমাদের আবেদনের জন্য সম্পূর্ণ অপ্রাসঙ্গিক।
(1..2_000_000).sum #=> 2000001000000
। আমার প্রিয় ভাষায় আরেকটি এক: sum [1 .. 2000000] --=> 2000001000000
। না আমার প্রিয়: Array.from({length: 2000001}, (v, k) => k).reduce((acc, el) => acc + el) //=> 2000001000000
। (সত্যি বলতে গেলে, শেষটি প্রতারণা করছে))
Integer
নির্বিচারে-নির্ভুলতা রয়েছে, যতক্ষণ না আপনি বরাদ্দযোগ্য র্যামটি চালিয়ে না যান ততক্ষণ এটি কোনও সংখ্যা ধরে রাখবে।
But with the 10,000,000,000 repetitions, the time taken by a check is still less than 1 nanosecond.
এটি লুপটি অনুকূলিত হওয়ার একটি ইঙ্গিত। এছাড়াও সেই বাক্যটি পূর্ববর্তী সংখ্যার সাথে দ্বিধা বোধ করে যা আমার কাছে খুব বৈধ বলে মনে হয়।
checked { }
আপনি কোডটির যে অংশগুলিতে পাটিগণিত ওভারফ্লো চেকগুলি করা উচিত তা চিহ্নিত করতে বিভাগটি ব্যবহার করতে পারেন । এটি পারফরম্যান্সের কারণে