রোজলিনে অ্যাসিঙ্ক স্টেট মেশিন ক্লাসগুলি (এবং স্ট্রাক্ট নয়) কেন?


87

আসুন এই খুব সহজ async পদ্ধতি বিবেচনা করুন:

static async Task myMethodAsync() 
{
    await Task.Delay(500);
}

আমি যখন ভিএস2013 (প্রাক রোজলিন সংকলক) দিয়ে এটি সংকলন করি তখন উত্পন্ন রাষ্ট্র-মেশিনটি একটি কাঠামো।

private struct <myMethodAsync>d__0 : IAsyncStateMachine
{  
    ...
    void IAsyncStateMachine.MoveNext()
    {
        ...
    }
}

আমি যখন এটি ভিএস2015 (রোজলিন) দিয়ে সংকলন করি তখন উত্পন্ন কোডটি হ'ল:

private sealed class <myMethodAsync>d__1 : IAsyncStateMachine
{
    ...
    void IAsyncStateMachine.MoveNext()
    {
        ...
    }
}

আপনি দেখতে পাচ্ছেন রোজলিন একটি শ্রেণি উত্পন্ন করে (এবং কোনও কাঠামো নয়)। যদি আমি পুরানো সংকলক (সিটিপি ২০১২২ অনুমান করি) পুরানো সংকলক (সিটিপি ২০১২২ অনুমান) এর প্রথম অ্যাসিঙ্ক / অপেক্ষার সহায়তার প্রথম প্রয়োগগুলি সঠিকভাবে মনে রাখি এবং তারপরে পারফরম্যান্সের কারণে এটি কাঠামোতে পরিবর্তিত হয়। (দেখুন (কিছু কিছু ক্ষেত্রে আপনি সম্পূর্ণরূপে বক্সিং এবং গাদা বরাদ্দ ... এড়াতে পারেন) এই )

রোজলিনে আবার কেন এটি পরিবর্তন করা হয়েছিল তা কি কেউ জানেন? (এটি সম্পর্কে আমার কোনও সমস্যা নেই, আমি জানি যে এই পরিবর্তনটি স্বচ্ছ এবং কোনও কোডের আচরণ পরিবর্তন করে না, আমি কেবল কৌতূহলী)

সম্পাদনা করুন:

@ ডামিয়েন_ই_ অবিশ্বাসীর (এবং উত্স কোড :)) এর উত্তর ইমো সবকিছু ব্যাখ্যা করে। রোজলিনের বর্ণিত আচরণ কেবলমাত্র ডিবাগ বিল্ডের জন্য প্রযোজ্য (এবং মন্তব্যটিতে উল্লিখিত সিএলআর সীমাবদ্ধতার কারণে এটি প্রয়োজন)। রিলিজে এটি একটি কাঠামো তৈরি করে (এর সমস্ত সুবিধা সহ ..)। সুতরাং এটি সম্পাদনা এবং চালিয়ে যাওয়া এবং উত্পাদনে আরও ভাল পারফরম্যান্স উভয়কেই সমর্থন করার জন্য খুব চতুর সমাধান বলে মনে হচ্ছে। আকর্ষণীয় স্টাফ, অংশ নেওয়া প্রত্যেকের জন্য ধন্যবাদ!


4
আমি সন্দেহ করি যে তারা সিদ্ধান্ত নিয়েছিলেন যে জটিলতা (পুনঃ পরিবর্তনযোগ্য স্ট্রাক্ট) এর পক্ষে উপযুক্ত নয়। asyncপদ্ধতির প্রায় সবসময়ই একটি সত্য অ্যাসিনক্রোনাস পয়েন্ট থাকে - এটি awaitএমন একটি নিয়ন্ত্রণ দেয় যা স্ট্রাক্টকে যাইহোক বক্স করা দরকার। আমি বিশ্বাস করি যে স্ট্রোকগুলি asyncসিঙ্ক্রোনালি চলমান যে পদ্ধতিগুলির জন্য কেবল মেমরির চাপকে মুক্তি দেয় ।
স্টিফেন ক্লিয়ারি

উত্তর:


112

আমার এ সম্পর্কে কোনও পূর্বানুমতি ছিল না, তবে রোজলিন যেহেতু আজকাল ওপেন সোর্স, তাই আমরা ব্যাখ্যাটির জন্য কোডটির মাধ্যমে শিকারে যেতে পারি।

এবং এখানে, AsyncRewriter এর 60 লাইনে আমরা পাই:

// The CLR doesn't support adding fields to structs, so in order to enable EnC in an async method we need to generate a class.
var typeKind = compilationState.Compilation.Options.EnableEditAndContinue ? TypeKind.Class : TypeKind.Struct;

সুতরাং, structগুলি ব্যবহার করার জন্য কিছু আবেদন থাকলেও, পদ্ধতিগুলির মধ্যে সম্পাদনা এবং চালিয়ে যাওয়ার অনুমতি দেওয়ার বড় জয়টি asyncঅবশ্যই আরও ভাল বিকল্প হিসাবে বেছে নেওয়া হয়েছিল।


18
খুব ভাল ধরা! এবং এর ভিত্তিতে আমি এটিও আবিষ্কার করেছি: এটি কেবল তখনই ঘটে যখন আপনি এটি ডিবাগে তৈরি করেন (বোঝা যায়, এটি আপনি যখন এনসি করেন ..), তবে রিলিজে তারা একটি কাঠামো তৈরি করে (স্পষ্টতই সক্ষম করুনডিটঅ্যান্ডকন্টিনিউ সেই ক্ষেত্রে মিথ্যা .. ।)। বিটিডব্লিউ আমি কোডটি সন্ধান করার চেষ্টা করেছি, কিন্তু এটি খুঁজে পেলাম না। অনেক ধন্যবাদ!
গ্রেগকালাপোস

3

এই জাতীয় কোনও কিছুর জন্য একটি যথাযথ উত্তর দেওয়া কঠিন (যদি না সংকলক দলের কেউই :) না নামেন) তবে আপনি কয়েকটি বিষয় বিবেচনা করতে পারেন:

স্ট্রাইকগুলির পারফরম্যান্স "বোনাস" সর্বদা একটি ট্রেড অফ। মূলত, আপনি নিম্নলিখিত পেতে:

  • মূল্য শব্দার্থক
  • সম্ভাব্য স্ট্যাক (এমনকি এমনকি নিবন্ধকরণ?) বরাদ্দ
  • ইন্ডিরিশন এড়ানো

অপেক্ষার মামলায় এর অর্থ কী? ঠিক আছে, আসলে ... কিছুই না। রাষ্ট্রের যন্ত্রটি স্ট্যাকের মধ্যে খুব অল্প সময়ের মধ্যেই রয়েছে - মনে রাখবেন, awaitকার্যকরভাবে কার্যকরভাবে একটি হয় return, সুতরাং পদ্ধতি স্ট্যাকটি মারা যায়; রাষ্ট্রীয় যন্ত্রটি অবশ্যই কোথাও সংরক্ষণ করতে হবে এবং অবশ্যই "কোথাও" গাদা থাকবে। স্ট্যাক আজীবন অ্যাসিক্রোনাস কোড ভাল ফিট করে না :)

এগুলি ছাড়াও, রাষ্ট্রীয় যন্ত্রগুলি স্ট্রিংগুলি সংজ্ঞায়িত করার জন্য কিছু ভাল নির্দেশিকা লঙ্ঘন করে:

  • structগুলি সর্বাধিক 16-বাইট বড় হওয়া উচিত - রাষ্ট্রীয় মেশিনে দুটি পয়েন্টার রয়েছে, যা নিজেরাই 16-বাইট সীমা পরিষ্কারভাবে 64-বিট পূরণ করে। এগুলি ছাড়াও, রাষ্ট্র নিজেই রয়েছে, সুতরাং এটি "সীমা" ছাড়িয়ে যায়। এটি কোনও বড় বিষয় নয় , যেহেতু সম্ভবত এটি কেবল রেফারেন্স দিয়েই গেছে তবে এটি লক্ষ্য করুন যে স্ট্রাক্টগুলির ক্ষেত্রে এটি কীভাবে ব্যবহারের ক্ষেত্রে পুরোপুরি খাপ খায় না - একটি কাঠামো যা মূলত একটি রেফারেন্স টাইপ।
  • structগুলি অপরিবর্তনীয় হওয়া উচিত - ভাল, সম্ভবত এটির খুব বেশি মন্তব্য করার প্রয়োজন নেই। এটি একটি রাষ্ট্রীয় মেশিন । আবার, এটি কোনও বড় বিষয় নয়, যেহেতু স্ট্রাক্টটি স্বয়ংক্রিয়ভাবে উত্পন্ন কোড এবং ব্যক্তিগত, তবে ...
  • structগুলি যৌক্তিকভাবে একটি একক মান উপস্থাপন করা উচিত। অবশ্যই এখানে ঘটনা নয়, কিন্তু ইতিমধ্যে ধরণের প্রথম স্থানে একটি পরিবর্তনীয় রাষ্ট্র থাকার থেকে অনুসরণ করে।
  • এটি ঘন ঘন বক্স করা উচিত নয় - এখানে সমস্যা নয়, যেহেতু আমরা সর্বত্র জেনেরিক ব্যবহার করছি । রাজ্যটি চূড়ান্তভাবে কোথাও কোথাও রয়েছে তবে কমপক্ষে এটি বক্স করা হচ্ছে না (স্বয়ংক্রিয়ভাবে)। আবার, এটি কেবল অভ্যন্তরীণভাবে ব্যবহৃত হয়েছে এটিকে এটিকে প্রায় অকার্যকর করে তোলে।

এবং অবশ্যই, এটি সব এমন ক্ষেত্রে হয় যেখানে কোনও বন্ধ নেই। আপনার যখন স্থানীয় (বা ক্ষেত্র) থাকে যা এই ক্ষেত্রগুলিকে অতিক্রম করে awaitতখন স্ট্রাক ব্যবহারের উপযোগিতা সীমাবদ্ধ করে রাষ্ট্রটি আরও ফুলে যায়।

এই সমস্ত দেওয়া, শ্রেণি পদ্ধতির স্পষ্টভাবে ক্লিনার, এবং আমি structপরিবর্তে ব্যবহার থেকে কোন লক্ষণীয় কর্মক্ষমতা বৃদ্ধি আশা করব না । জড়িত বস্তুর সকল অনুরূপ জীবনকাল নেই, তাই মেমরির পারফরম্যান্সের উন্নতি করার একমাত্র উপায় করতে হবে সব তাদের structযা সাধারণ ক্ষেত্রে অসম্ভব, অবশ্যই - (উদাহরণস্বরূপ, কিছু বাফারে দোকান) গুলি। এবং বেশিরভাগ ক্ষেত্রে যেখানে আপনি awaitপ্রথম স্থানে ব্যবহার করতেন (এটি কিছু অবিচ্ছিন্ন আই / ও কাজ) ইতিমধ্যে অন্যান্য শ্রেণিগুলিতে জড়িত - উদাহরণস্বরূপ, ডেটা বাফারস, স্ট্রিংস ... এটি এমন কোনও সম্ভাবনা awaitনয় যা আপনি কেবল 42কোনও কাজ না করে ফিরে আসেন গাদা বরাদ্দ।

শেষ পর্যন্ত, আমি কেবলমাত্র যেখানে আপনি সত্যিকারের পারফরম্যান্সের পার্থক্য দেখতে পাচ্ছেন সেটিই বেঞ্চমার্ক হবে। এবং মানদণ্ডের জন্য অনুকূলিতকরণ একটি নির্বোধ ধারণা, কমপক্ষে ...


আপনি যখন যান এবং উত্সটি পড়তে পারেন তখন আপনাকে সর্বদা সংকলক দলের সদস্যের প্রয়োজন হয় না এবং তারা একটি সহায়ক মন্তব্য রেখে গেছেন :-)
ড্যামিয়েন_সে_বিশ্বাসীরা

4
@ ড্যামিয়েন_সে_ অবিশ্বাস্য হ্যাঁ, এটি অবশ্যই একটি দুর্দান্ত সন্ধান ছিল, আমি ইতিমধ্যে আপনার উত্তরটিকে
উজ্জীবিত করেছি

4
কোডটি async চালিত না হয় ক্ষেত্রে স্ট্রাক্ট অনেক সাহায্য করে, উদাহরণস্বরূপ ডেটা ইতিমধ্যে একটি বাফারে রয়েছে।
ইয়ান রিংরোজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.