লিনাক কি তলদেশে প্রদর্শিত হওয়ার চেয়ে বেশি দক্ষ?


13

আমি যদি এরকম কিছু লিখি:

var things = mythings
    .Where(x => x.IsSomeValue)
    .Where(y => y.IsSomeOtherValue)

এটি কি একই:

var results1 = new List<Thing>();
foreach(var t in mythings)
    if(t.IsSomeValue)
        results1.Add(t);

var results2 = new List<Thing>();
foreach(var t in results1)
    if(t.IsSomeOtherValue)
        results2.Add(t);

বা কভারগুলির নীচে এমন কোনও জাদু রয়েছে যা আরও এইরকম কাজ করে:

var results = new List<Thing>();
foreach(var t in mythings)
    if(t.IsSomeValue && t.IsSomeOtherValue)
        results.Add(t);

বা এটি সম্পূর্ণ আলাদা কিছু?


4
আপনি এটি আইএলএসপি-তে দেখতে পারেন।
কেওসপ্যান্ডিয়ন

1
এটি আইএলএসপি আপনার বন্ধু বলে প্রথম কিন্তু দ্বিতীয় চ্যাসপ্যান্ডিয়নের উত্তরের চেয়ে দ্বিতীয় উদাহরণের মতো।
মাইকেল

উত্তর:


27

লিনকুইয়ের প্রশ্নগুলি অলস । এর অর্থ কোড:

var things = mythings
    .Where(x => x.IsSomeValue)
    .Where(y => y.IsSomeOtherValue);

খুব অল্প করে। প্রকৃত গণনাযোগ্য ( mythings) কেবল তখনই গণনা করা হয় যখন ফলাফলযুক্ত গণনা করা ( things) গ্রাস করা হয়, যেমন foreachলুপ দ্বারা .ToList(), বা .ToArray()

আপনি যদি কল করেন তবে things.ToList()এটি গণকগণের কাছ থেকে সম্ভবত কিছুটা (সাধারণত তুচ্ছ) ওভারহেড সহ মোটামুটিভাবে আপনার পরবর্তী কোডের সমান equivalent

তেমনিভাবে, আপনি যদি ফোরচ লুপ ব্যবহার করেন:

foreach (var t in things)
    DoSomething(t);

এটি পারফরম্যান্সেও অনুরূপ:

foreach (var t in mythings)
    if (t.IsSomeValue && t.IsSomeOtherValue)
        DoSomething(t);

অগণিতদের জন্য অলসতার পদ্ধতির কিছু কার্যকারিতা সুবিধা (সমস্ত ফলাফল গণনা করার জন্য এবং একটি তালিকায় সেগুলি সঞ্চয় করার বিপরীতে) হ'ল এটি খুব কম স্মৃতি ব্যবহার করে (যেহেতু কেবলমাত্র একটি ফলাফল একসাথে সংরক্ষণ করা হয়) এবং এর কোনও উল্লেখযোগ্য পরিমাণ নেই -প্রথম খরচ

যদি সংখ্যাটি কেবল আংশিকভাবে গণনা করা হয় তবে এটি বিশেষভাবে গুরুত্বপূর্ণ। এই কোডটি বিবেচনা করুন:

things.First();

যেভাবে লিনকিউ বাস্তবায়িত করা হয়েছে, mythingsকেবলমাত্র সেখানে আপনার প্রাথমিক অবস্থার সাথে মেলে এমন প্রথম উপাদান পর্যন্ত গণনা করা হবে। যদি সেই উপাদানটি তালিকার শুরুতে থাকে তবে এটি ও (এন) এর পরিবর্তে বিশাল পারফরম্যান্স বুস্ট (যেমন ও (1)) হতে পারে।


1
লিনকিউ এবং সমতুল্য কোড ব্যবহারের মধ্যে পারফরম্যান্সের একটি পার্থক্য foreachহ'ল লিনকিউ প্রতিনিধি আমন্ত্রণগুলি ব্যবহার করে, এর কিছু ওভারহেড থাকে। যখন শর্তগুলি খুব দ্রুত সম্পাদন করে (যা তারা প্রায়শই করেন) এটি তাত্পর্যপূর্ণ হতে পারে।
সুইভ

2
এটাই আমি বোঝাচ্ছি ওভারহেডের গণক দ্বারা। এটি কয়েকটি (বিরল) ক্ষেত্রে ইস্যু হতে পারে তবে আমার অভিজ্ঞতায় যা প্রায়শই হয় না - সাধারণত যে সময় লাগে এটি খুব কম হয় বা আপনি যে কাজগুলি করছেন তার দ্বারা এটি খুব বেশি পরিমাণে ছাড়িয়ে যায়।
সায়ানফিশ

Linq এর অলস মূল্যায়ন একটি কদর্য সীমাবদ্ধতা মত পদ্ধতির মাধ্যমে ছাড়া একটি একটি শুমার "স্ন্যাপশট" নিতে কোন উপায় যে নেই ToListবা ToArray। যদি এ জাতীয় জিনিসটি যথাযথভাবে তৈরি করা IEnumerableহত তবে সবকিছু তৈরি না করে ভবিষ্যতে যে দিকগুলি পরিবর্তন হতে পারে তার "স্ন্যাপশট" করতে একটি তালিকা জিজ্ঞাসা করা সম্ভব হত।
সুপারক্যাট

7

নিম্নলিখিত কোড:

var things = mythings
    .Where(x => x.IsSomeValue)
    .Where(y => y.IsSomeOtherValue);

কোন কিছুর সমতুল্য, অলস মূল্যায়নের কারণে কিছুই হবে না।

var things = mythings
    .Where(x => x.IsSomeValue)
    .Where(y => y.IsSomeOtherValue)
    .ToList();

ভিন্ন, কারণ মূল্যায়ন আরম্ভ হবে।

প্রতিটি আইটেম mythingsপ্রথম দেওয়া হবে Where। এটি পাস হলে দ্বিতীয়টিকে দেওয়া হবে Where। যদি এটি পাস হয় তবে এটি আউটপুটের অংশ হবে।

সুতরাং এটি এর মতো আরও দেখাচ্ছে:

var results = new List<Thing>();
foreach(var t in mythings)
{
    if(t.IsSomeValue)
    {
        if(t.IsSomeOtherValue)
        {
            results.Add(t);
        }
    }
}

7

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

আসুন আপনি কল ToListকরুন কল্পনা করুন things

Enumerable.Whereরিটার্ন বাস্তবায়ন a Enumerable.WhereListIterator। আপনি যখন এটিকে কল Whereকরুন WhereListIterator(ওরফে চেইনিং- Whereকলস), আপনি আর কল করবেন না Enumerable.Where, তবে Enumerable.WhereListIterator.Whereযা প্রকৃতপক্ষে পূর্বাভাসকে (ব্যবহার করে Enumerable.CombinePredicates) একত্রিত করে ।

সুতরাং এটি আরও পছন্দ if(t.IsSomeValue && t.IsSomeOtherValue)


"একটি গণনার ফিরিয়ে দেয় hereWirListIterator" এটি আমার জন্য ক্লিক করে। সম্ভবত একটি খুব সাধারণ ধারণা, কিন্তু আমি আইএলএসপি এর সাথে নজর রাখছি না। ধন্যবাদ
কন্ডিশন

আপনি যদি গভীরতার বিশ্লেষণে আরও আগ্রহী হন তবে জন স্কিটির এই অপ্টিমাইজেশনের পুনরায় বাস্তবায়ন দেখুন।
পরিবেশন করুন

1

না এটা এক নয়। আপনার উদাহরণে thingsএকটি হ'ল IEnumerable, যা এই মুহুর্তে কেবলমাত্র একটি পুনরুক্তিযোগ্য, প্রকৃত অ্যারে বা তালিকা নয়। thingsতবুও যেহেতু ব্যবহৃত হয় না, লুপটি কখনও মূল্যায়নও করা হয় না। টাইপটি লিনক নির্দেশাবলী অনুসারে IEnumerableউপাদানগুলির মাধ্যমে পুনরাবৃত্তি করতে yieldএবং আরও নির্দেশাবলীর সাথে আরও প্রক্রিয়া করতে দেয়, যার অর্থ আপনার কাছে কেবলমাত্র একটি লুপ থাকে।

তবে আপনি .ToArray()বা এর মতো কোনও নির্দেশ যুক্ত করার সাথে সাথে .ToList()আপনি একটি প্রকৃত ডেটা কাঠামো তৈরির আদেশ দিচ্ছেন, এভাবে আপনার শৃঙ্খলে সীমানা রেখে।

এই সম্পর্কিত এসও প্রশ্নটি দেখুন: /programming/2789389/how-do-i-implement-ienumerable

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.