ইনভোক এবং ডায়নামিক ইনভোকের মধ্যে পার্থক্য


128

প্রতিনিধিদের মধ্যে ইনভোক এবং ডায়নামিক ইনভোকের মধ্যে পার্থক্য কী? দয়া করে আমাকে এমন কিছু কোড উদাহরণ দিন যা এটি দুটি পদ্ধতির মধ্যে পার্থক্য ব্যাখ্যা করে।

উত্তর:


206

আপনার যখন কোনও প্রতিনিধি উদাহরণ রয়েছে, আপনি সঠিক ধরণটি জানেন বা আপনি হয়ত জানেন যে এটি একটি Delegate। আপনি যদি সঠিক ধরনটি জানেন তবে আপনি ব্যবহার করতে পারবেন Invokeযা খুব দ্রুত - সবকিছু ইতিমধ্যে প্রাক-বৈধ। উদাহরণ স্বরূপ:

Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);

যাহোক! যদি আপনি কেবল এটি জানেন Delegateতবে এটি প্যারামিটারগুলি ম্যানুয়ালি সমাধান করতে হবে - এতে আনবক্সিং ইত্যাদি জড়িত থাকতে পারে - প্রচুর প্রতিচ্ছবি চলছে। উদাহরণ স্বরূপ:

Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);

দ্রষ্টব্য আমি জড়িত argsতা পরিষ্কার করার জন্য দীর্ঘ হাতটি লিখেছি an object[]এখানে প্রচুর অতিরিক্ত ব্যয় হয়:

  • অ্যারে
  • পাস হওয়া যুক্তি যাচাই করা প্রকৃত পক্ষে "ফিট" MethodInfo
  • আনবক্সিং ইত্যাদি প্রয়োজনীয় হিসাবে
  • প্রতিফলন-ডাকা
  • তারপরে কলকারকে ফেরতের মানটি প্রক্রিয়াকরণের জন্য কিছু করা দরকার

মূলত, DynamicInvokeআপনি যখন পারেন তখন এড়িয়ে চলুন । Invokeআপনার কাছে থাকা সমস্তগুলি একটি Delegateএবং একটি না হলে সর্বদা পছন্দসই object[]

একটি পারফরম্যান্স তুলনার জন্য, ডিবাগারের বাইরে নিম্নলিখিতটি প্রকাশের মোডে (একটি কনসোল এক্সপি) প্রিন্ট করে:

Invoke: 19ms
DynamicInvoke: 3813ms

কোড:

Func<int,int> twice = x => x * 2;
const int LOOP = 5000000; // 5M
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
    twice.Invoke(3);
}
watch.Stop();
Console.WriteLine("Invoke: {0}ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
    twice.DynamicInvoke(3);
}
watch.Stop();
Console.WriteLine("DynamicInvoke: {0}ms", watch.ElapsedMilliseconds);

3
এর অর্থ কি ব্যবহারের ক্ষেত্রে ডায়নামিকআইভোক কম্পাইলার প্রতিনিধিদের অনুরোধ পরিচালনা করতে আরও আইএল কোড তৈরি করে?
টেস্টকোডার

2
@ টেষ্টকোডার নং, এটি প্রতিবিম্বটি ব্যবহার করবে
মার্ক গ্রাভেল

@ মার্কগ্রাভেল যখন আমি এমন পদ্ধতিতে চেষ্টা করি যা ইভেন্ট উত্থাপন করে, আমি প্রথম পদ্ধতির কলটি প্রায় 0,7766 এমএস নিচ্ছেন তবে দ্বিতীয়টি প্রায় 0,0568 এমএস নিচ্ছে। প্রথমটি যখন আমন্ত্রণ করা হয় তখন এটি ডায়নামিকআইভনোকে বা তদ্বিপরীত থেকে বেশি সময় নেয়। আমি যখন 1 টি লুপ দিয়ে আপনার উদাহরণটি চেষ্টা করেছি এবং এমএসে দেখি Invoke: 0,0478ms, DynamicInvoke: 0,053ms। আপনি কেন তাদের সাথে 1 টিরও বেশি কল তুলনা করছেন? এবং কেন প্রথমটি ফাংশনের দ্বিতীয় কলের চেয়ে বেশি সময় নেয়?
uzay95

4
@ uzay95 পদ্ধতির প্রথম কলটি সিএলআর দ্বারা জেআইটি সংকলন ঘটায় - প্রক্রিয়াটি শুরুর পরে এটি প্রথমবারের মতো কোনও পদ্ধতির ক্ষেত্রে প্রযোজ্য। এই ধরণের দৃশ্যে আপনি তিনটি জিনিসের মধ্যে একটি করতে পারেন: (১) পদ্ধতিটি বেশ কয়েকবার চালান যাতে প্রথম কল করার সময়টি চূড়ান্ত ফলাফলের জন্য তুচ্ছ হয়ে যায়, (২) আপনার পরে না হওয়া পর্যন্ত পরিমাপ শুরু করবেন না পদ্ধতিটি একবার বলেছিলেন বা (3) ngen.exe (ওভারকিল) ব্যবহার করুন। এই পোস্টটি এটি যথেষ্ট ভালভাবে ব্যাখ্যা করেছে ... stackoverflow.com/questions/4446203/…
কোয়ান্টা

@ Marc-gravell আপনি যেহেতু এটি এর পদ্ধতি স্বাক্ষর যুক্তরাষ্ট্রের DynamicInvoke পাস একটি অ্যারে নির্মাণ করার প্রয়োজন হবে না প্যারাম args পরামিতি জন্য এখানে ক্লিক করুন।
zodo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.