এই ক্যাশিং কৌশলটির জন্য আমার কোন ডেটা স্ট্রাকচার ব্যবহার করা উচিত?


11

আমি একটি নেট নেট অ্যাপ্লিকেশনটিতে কাজ করছি, এটি দ্বিগুণ ফিরতে দুটি ডাবলগুলির জন্য একটি ব্যয়বহুল গণনা করে। এই গণনা কয়েক হাজার আইটেমের প্রতিটি জন্য সঞ্চালিত হয় । এই গণনাগুলি Taskথ্রেডপুলের থ্রেডে একটিতে সঞ্চালিত হয় ।

কয়েকটি প্রাথমিক পরীক্ষায় দেখা গেছে যে একই গণনাগুলি বারবার সম্পাদিত হয়, তাই আমি এন ফলাফলগুলি ক্যাশে করতে চাই । যখন ক্যাশে পূর্ণ হয়, আমি সর্বনিম্ন- প্রায়শই ব্যবহৃত ব্যবহৃত আইটেমটি ফেলে দিতে চাই । ( সম্পাদনা: আমি বুঝতে পেরেছিলাম যে প্রায়শই প্রায়শই বোঝা যায় না, কারণ যখন ক্যাশে পূর্ণ থাকে এবং আমি একটি ফলাফল নতুন সুনির্দিষ্ট সাথে প্রতিস্থাপন করতাম, তবে প্রায়শই ব্যবহৃত হত এবং পরের বার একটি নতুন ফলাফল গণনা করার সাথে সাথে প্রতিস্থাপন করা হত এবং ক্যাশে যুক্ত)

এটি বাস্তবায়নের জন্য, আমি ইনপুট এবং ক্যাশেড ফলাফলগুলি সংরক্ষণ করার জন্য একটি Dictionary<Input, double>(যেখানে Inputদুটি শ্রেণির ইনপুট ডাবল ভ্যালু সংরক্ষণ করে একটি মিনি-ক্লাস হবে ) ব্যবহার করার কথা ভাবছিলাম । যাইহোক, আমাকে শেষ বার কখন ফলাফল ব্যবহার করা হয়েছিল সে সম্পর্কেও নজর রাখতে হবে। এর জন্য আমি মনে করি ক্যাশে পূর্ণ হওয়ার সময় ডিকোনারি থেকে কোনও ফলাফল সরিয়ে ফেলতে আমার প্রয়োজনীয় তথ্য সংরক্ষণের জন্য আমার দ্বিতীয় সংগ্রহের প্রয়োজন হবে। আমি উদ্বিগ্ন যে এই তালিকাটি ক্রমাগত বাছাই করা নেতিবাচকভাবে প্রভাব ফেলবে।

এটি করার কি আরও ভাল (অর্থাত্ আরও পারফরম্যান্ট) উপায় আছে, বা এমন একটি সাধারণ ডেটা স্ট্রাকচার, যা সম্পর্কে আমি অজানা? আমার সমাধানটির অনুকূলতা নির্ধারণ করতে আমার কী ধরণের জিনিসগুলি প্রোফাইল / মাপ করা উচিত?

উত্তর:


12

আপনি যদি কোনও এলআরইউ উচ্ছেদের ক্যাশে ব্যবহার করতে চান (সর্বশেষে ব্যবহৃত উচ্ছেদের), তবে সম্ভবত ব্যবহারের জন্য ডেটা স্ট্রাকচারগুলির একটি ভাল সংমিশ্রণটি হ'ল:

  • বিজ্ঞপ্তিযুক্ত লিঙ্ক তালিকা (অগ্রাধিকার সারি হিসাবে)
  • অভিধান

এই জন্যই:

  • লিঙ্কযুক্ত তালিকায় একটি ও (1) সন্নিবেশ এবং অপসারণের সময় রয়েছে
  • তালিকাটি পূর্ণ হলে তালিকা নোডগুলি পুনরায় ব্যবহার করা যেতে পারে এবং কোনও অতিরিক্ত বরাদ্দ সঞ্চালনের প্রয়োজন হয় না।

বেসিক অ্যালগরিদমকে এভাবে কাজ করা উচিত:

তথ্য কাঠামো

LinkedList<Node<KeyValuePair<Input,Double>>> list; Dictionary<Input,Node<KeyValuePair<Input,Double>>> dict;

  1. ইনপুট গৃহীত হয়েছে
  2. অভিধানে যদি কী থাকে
    • নোডে সঞ্চিত মানটি ফেরত দিন এবং নোডটিকে তালিকার শুরুতে সরান
  3. অভিধানে কীটি না থাকলে
    • মান গণনা
    • তালিকার শেষ নোডে মান সংরক্ষণ করুন
    • যদি শেষের কোনও মান না থাকে তবে অভিধান থেকে পূর্বের কীটি সরিয়ে ফেলুন
    • শেষ নোডটি প্রথম অবস্থানে নিয়ে যান।
    • অভিধানে (ইনপুট, নোড) কী মান জোড়া সংরক্ষণ করুন।

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


ভাল পয়েন্টস, এখন পর্যন্ত সেরা ধারণা, আইএমএইচও। আমি আজকে এর উপর ভিত্তি করে একটি ক্যাশে প্রয়োগ করেছি এবং এটি প্রোফাইল করতে হবে এবং আগামীকাল এটি কতটা ভাল সম্পাদন করবে তা দেখতে হবে।
ব্যক্তিগতনেেক্সাস

3

এটি औसत পিসিতে আপনার নিজের হাতে থাকা প্রসেসিং শক্তি দিয়ে একটি একক গণনায় যাওয়ার প্রচেষ্টার মতো বলে মনে হচ্ছে। এছাড়াও, আপনি এখনও মান প্রতিটি অনন্য যুগল জন্য আপনার হিসাব প্রথম কল ব্যয় তাই 100,000 অনন্য মান জোড়া এখনও সময় খরচ হবে করব এন ন্যূনতম * 100,000। বিবেচনা করুন যে অভিধানটি বড় হওয়ার সাথে সাথে আপনার অভিধানে অ্যাক্সেসের মানগুলি সম্ভবত ধীর হয়ে যাবে। আপনি কি নিশ্চিত করতে পারেন যে আপনার অভিধানের অ্যাক্সেসের গতি আপনার গণনার গতির বিরুদ্ধে যুক্তিসঙ্গত রিটার্ন দেওয়ার জন্য যথেষ্ট ক্ষতিপূরণ দেবে?

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


1
দুর্ভাগ্যক্রমে, আপাতত গণনা অ্যালগরিদম পরিবর্তন করা যায় না, কারণ এটি একটি তৃতীয় পক্ষের গ্রন্থাগার যা কিছু উন্নত গণিত ব্যবহার করে যা প্রাকৃতিকভাবে সিপিইউ নিবিড়। যদি পরবর্তী সময়ে পুনরায় কাজ করা হয় তবে আমি প্রস্তাবিত প্রোফাইলিং সরঞ্জামগুলি অবশ্যই পরীক্ষা করে দেখব। তদ্ব্যতীত, গণনাটি প্রায়শই পারফর্মার হবে, কখনও কখনও অভিন্ন ইনপুট সহ, তাই প্রাথমিক প্রোফাইলিং খুব নিষ্পাপ ক্যাচিং কৌশল নিয়েও একটি সুস্পষ্ট উপকার দেখিয়েছে।
পার্সোনালনেক্সাস

0

একটি চিন্তা কেন কেবল ক্যাশে এন ফলাফল? N যদি 300,000 হয় তবে আপনি কেবল 7.2MB মেমরি ব্যবহার করবেন (টেবিলের কাঠামোর জন্য অতিরিক্ত যাই হোক না কেন)। এটি অবশ্যই তিনটি বিট ডাবলসকে ধরে নিয়েছে। আপনি যদি স্মৃতিশক্তি ছাড়িয়ে যাওয়ার বিষয়ে উদ্বিগ্ন না হন তবে জটিল ক্যালকুলেশন রুটিনে আপনি কেবল মেমোয়েজেশন প্রয়োগ করতে পারেন।


এখানে কেবল একটি ক্যাশে থাকবে না, তবে প্রতি "আইটেম" প্রতি একটি যা আমি বিশ্লেষণ করছি এবং এই আইটেমগুলির মধ্যে কয়েক লক্ষ থাকতে পারে।
পার্সোনালনেক্সাস

কোন আইটেমটি কী 'আইটেম' ইনপুট থেকে আসে তা বিবেচনা করে? পার্শ্ব প্রতিক্রিয়া আছে?
জে কে।

@jk। বিভিন্ন আইটেম গণনা খুব আলাদা ইনপুট উত্পাদন করবে। যেহেতু এর অর্থ হ'ল সামান্য ওভারল্যাপ হবে তাই আমি মনে করি না যে এগুলিকে একক ক্যাশে রাখা অর্থপূর্ণ হয়। তদুপরি, বিভিন্ন আইটেম বিভিন্ন থ্রেডে থাকতে পারে, তাই ভাগ করে নেওয়া অবস্থা এড়াতে, আমি ক্যাশেগুলি আলাদা রাখতে চাই।
পার্সোনালনেক্সাস

@ পার্সোনালনেক্সাস আমি এটি নিরূপণে নিযুক্ত করি সেখানে আরও 2 প্যারামিটার গণনায় জড়িত আছে? অন্যথায়, আপনার এখনও মূলত f (x, y) = কিছু স্টাফ করুন। প্লাস ভাগ করে নেওয়া রাষ্ট্রের মনে হচ্ছে এটি বাধা না দিয়ে পারফরম্যান্সে সহায়তা করবে?
পিটার স্মিথ

@ পিটারস্মিথ দুটি পরামিতি হ'ল প্রধান ইনপুট। অন্যরা রয়েছে, তবে এগুলি খুব কমই পরিবর্তিত হয়। তারা যদি করে তবে আমি পুরো ক্যাশে ফেলে দেব। "ভাগ করা রাষ্ট্র" দ্বারা আমি সমস্ত বা একটি গ্রুপের আইটেমের জন্য একটি ভাগ করা ক্যাশে বোঝাতে চাইছি। যেহেতু এটি অন্য কোনও উপায়ে লক করা বা সিঙ্ক্রোনাইজ করা দরকার, এটি কার্য সম্পাদনে বাধা সৃষ্টি করবে। ভাগ রাষ্ট্র কর্মক্ষমতা প্রভাব আরো
ব্যক্তিগতনেেক্সাস

0

দ্বিতীয় সংগ্রহের সাথে পন্থাটি ঠিক আছে। এটি একটি অগ্রাধিকারের সারি হওয়া উচিত যা মিনি মানগুলি দ্রুত সন্ধান / মুছে ফেলার অনুমতি দেয় এবং কিউয়ের মধ্যে অগ্রাধিকারগুলি পরিবর্তন (বৃদ্ধি) করতে পারে (পরের অংশটি হার্ড, সবচেয়ে সাধারণ প্রিও সারির প্রয়োগগুলির দ্বারা সমর্থিত নয়)। , C5 গ্রন্থাগার যেমন একটি সংগ্রহ, এটা বলা হয় হয়েছে IntervalHeap

বা অবশ্যই, আপনি নিজের সংগ্রহ তৈরি করার চেষ্টা করতে পারেন, এর মতো কিছু SortedDictionary<int, List<InputCount>>। ( InputCountঅবশ্যই Inputআপনার Countমানের সাথে আপনার ডেটা সমন্বিত বর্গ হতে হবে )

আপনার গণনা মান পরিবর্তন করার সময় সেই সংগ্রহটি আপডেট করে কোনও উপাদান সরিয়ে এবং পুনরায় সন্নিবেশ করে প্রয়োগ করা যেতে পারে।


0

পিটার স্মিথের উত্তরে যেমন উল্লেখ করা হয়েছে, আপনি যে প্যাটার্নটি প্রয়োগের চেষ্টা করছেন সেটি মেমোয়েজেশন বলে । সি # তে পার্শ্ব প্রতিক্রিয়া ছাড়াই স্বচ্ছভাবে স্মৃতিচারণ বাস্তবায়ন করা বেশ কঠিন hard সি # তে ক্রিয়ামূলক প্রোগ্রামিংয়ে অলিভার স্টর্মের বইটি একটি সমাধান দেয় (কোড ডাউনলোডের জন্য উপলব্ধ, অধ্যায় 10)।

এফ # তে এটি আরও সহজ হবে। অবশ্যই, অন্য একটি প্রোগ্রামিং ভাষা ব্যবহার শুরু করা বড় সিদ্ধান্ত, তবে এটি বিবেচনা করার মতো হতে পারে। বিশেষত জটিল গণনায়, স্মৃতিচারণের চেয়ে প্রোগ্রামকে আরও সহজ করার জন্য এটি বাধ্য।

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