ফাংশনাল প্রোগ্রামিংয়ে, বেশিরভাগ ডেটা স্ট্রাকচার অপরিবর্তনীয় থাকার জন্য আরও বেশি মেমরির ব্যবহার প্রয়োজন?


63

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


7
এর অর্থ এটি হতে পারে তবে বেশিরভাগ অপরিবর্তনীয় ডেটা স্ট্রাকচার পরিবর্তনের জন্য অন্তর্নিহিত ডেটা পুনরায় ব্যবহার করে। এরিক লিপার্টের সি #
ওডে

3
আমি পিউলি ফাংশনাল ডেটা স্ট্রাকচারগুলি একবার দেখে নেব, এটি
হস্তেল

1
মেমরির পরিবর্তে চলমান সময়ের সাথে সম্পর্কিত এই উত্তরটি আপনার জন্যও আকর্ষণীয় হতে পারে: stackoverflow.com/questions/1990464/…
9000

1
: আপনি এই আকর্ষণীয় হতে পারে en.wikipedia.org/wiki/Static_single_assignment_form
শন McSomething

উত্তর:


35

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


24

কার্যকরী প্রোগ্রামিংয়ে যেহেতু প্রায় সমস্ত ডেটা স্ট্রাকচার অপরিবর্তনীয়, যখন রাষ্ট্রকে একটি নতুন কাঠামো তৈরি করতে হয়। এর অর্থ কি আরও অনেক বেশি মেমোরি ব্যবহার হয়?

এটি ডেটা কাঠামোর উপর নির্ভর করে, আপনি যে সঠিক পরিবর্তনগুলি করেছেন এবং কিছু ক্ষেত্রে অপটিমাইজার। একটি উদাহরণ হিসাবে একটি তালিকার অর্থ প্রদান বিবেচনা করা যাক:

list2 = prepend(42, list1) // list2 is now a list that contains 42 followed
                           // by the elements of list1. list1 is unchanged

এখানে অতিরিক্ত মেমরির প্রয়োজনীয়তা স্থির - কলিংয়ের রানটাইম ব্যয়ও তাই prepend। কেন? কারণ prependকেবল একটি নতুন ঘর তৈরি করে যার 42মাথা এবং list1লেজ হিসাবে। এটি list2অর্জনের জন্য এটি অনুলিপি বা অন্যথায় পুনরাবৃত্তি করতে হবে না। এটি, সংরক্ষণের জন্য প্রয়োজনীয় মেমরি বাদে 42, list2একই মেমরিটি ব্যবহার করে যা পুনরায় ব্যবহার করে list1। উভয় তালিকা অপরিবর্তনীয়, এই ভাগ করে নেওয়া পুরোপুরি নিরাপদ।

একইভাবে, ভারসাম্যযুক্ত কাঠের কাঠামোর সাথে কাজ করার সময়, বেশিরভাগ ক্রিয়াকলাপে কেবলমাত্র অতিরিক্ত স্থানের পরিমাণের প্রয়োজন হয় কারণ সমস্ত কিছু, তবে গাছের একটি পথ ভাগ করা যায়।

অ্যারেগুলির জন্য পরিস্থিতি কিছুটা আলাদা। এ কারণেই, অনেকগুলি এফপি ভাষায়, অ্যারেগুলি সাধারণত ব্যবহৃত হয় না। যাইহোক, আপনি যদি এই লাইনের পরে এমন কিছু করেন arr2 = map(f, arr1)এবং arr1আর কখনও ব্যবহার না করেন তবে একটি স্মার্ট অপ্টিমাইজার আসলে একটি কোড তৈরি করতে পারে যা arr1নতুন অ্যারে তৈরি করার পরিবর্তে পরিবর্তিত হয় (প্রোগ্রামটির আচরণকে প্রভাবিত না করে)। সেক্ষেত্রে পারফরম্যান্স অবশ্যই এক অপরিহার্য ভাষায় হবে।


1
আগ্রহের বাইরে, কোন ভাষা প্রয়োগের শেষের দিকে আপনি বর্ণিত হিসাবে স্থানটিকে পুনরায় ব্যবহার করবেন?

@ ডেলানান আমার বিশ্ববিদ্যালয়ে কিউব নামে একটি গবেষণা ভাষা ছিল যা এটি করেছিল did যদিও বন্য ভাষা ব্যবহার করে এমন কোনও ব্যবহার আছে কিনা তা আমি জানি না। তবে হাস্কেলের ফিউশন অনেক ক্ষেত্রে একই প্রভাব অর্জন করতে পারে।
sepp2k

7

নিষ্পাপ বাস্তবায়নগুলি প্রকৃতপক্ষে এই সমস্যাটিকে উদ্ভাসিত করবে - আপনি যখন বিদ্যমান জায়গায় আপডেট করার পরিবর্তে একটি নতুন ডেটা কাঠামো তৈরি করেন, আপনার কিছুটা ওভারহেড থাকতে হবে।

বিভিন্ন ভাষার সাথে এটির আচরণ করার বিভিন্ন উপায় রয়েছে এবং তাদের বেশিরভাগ ব্যবহার কৌশলও রয়েছে।

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

অন্য একটি বিভিন্ন ধরণের ডেটা স্ট্রাকচার বাছাই করছে। যেখানে অ্যারেগুলি হ'ল আবশ্যকীয় ভাষাগুলিতে ডেটা স্ট্রাকচারের তালিকা থাকে (সাধারণত ডাইনামিক-রিলোকেশন ধারক যেমন std::vectorসি ++ এর মধ্যে আবৃত থাকে ), কার্যকরী ভাষাগুলি প্রায়শই লিঙ্কযুক্ত তালিকাগুলি পছন্দ করে। একটি লিঙ্কযুক্ত তালিকার সাথে, একটি প্রিপেন্ড অপারেশন ('কনস') বিদ্যমান তালিকাকে নতুন তালিকার লেজ হিসাবে পুনরায় ব্যবহার করতে পারে, তাই যা সত্যিই বরাদ্দ হয়ে থাকে সেগুলিই নতুন তালিকার প্রধান। অন্যান্য ধরণের ডেটা স্ট্রাকচার - সেট, গাছ, আপনি এটির নামকরণের জন্য অনুরূপ কৌশল বিদ্যমান।

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


বাহ, একটি ছোট উত্তর এবং এত বেশি তথ্য / অন্তর্দৃষ্টি। আপনাকে ধন্যবাদ :)
গেরি

3

আমি কেবল ক্লোজার সম্পর্কে কিছুটা জানি এবং এটি অপরিবর্তনীয় ডেটা স্ট্রাকচারগুলি

Clojure অপরিবর্তনীয় তালিকা, ভেক্টর, সেট এবং মানচিত্রের একটি সেট সরবরাহ করে। যেহেতু সেগুলি পরিবর্তন করা যায় না, অপরিবর্তনীয় সংগ্রহ থেকে 'যুক্ত' বা 'মুছে ফেলার' অর্থ পুরানোের মতো তবে প্রয়োজনীয় পরিবর্তনের সাথে একটি নতুন সংগ্রহ তৈরি করা। দৃistence়তা হল এমন একটি শব্দ যা সম্পত্তির বর্ণনা দিতে ব্যবহৃত হয় যেখানে সংগ্রহের পুরানো সংস্করণটি 'পরিবর্তন' এর পরেও উপলব্ধ এবং সংগ্রহটি বেশিরভাগ ক্রিয়াকলাপের জন্য তার কার্য সম্পাদনের গ্যারান্টি বজায় রাখে। বিশেষত এর অর্থ হ'ল নতুন সংস্করণটি সম্পূর্ণ অনুলিপি ব্যবহার করে তৈরি করা যায় না, কারণ এর জন্য রৈখিক সময় প্রয়োজন। অনিবার্যভাবে, অবিচ্ছিন্ন সংগ্রহগুলি লিঙ্কযুক্ত ডেটা স্ট্রাকচার ব্যবহার করে প্রয়োগ করা হয়, যাতে নতুন সংস্করণ পূর্ববর্তী সংস্করণটির সাথে কাঠামো ভাগ করতে পারে।

গ্রাফিকালি, আমরা এর মতো কিছু উপস্থাপন করতে পারি:

(def my-list '(1 2 3))

    +---+      +---+      +---+
    | 1 | ---> | 2 | ---> | 3 |
    +---+      +---+      +---+

(def new-list (conj my-list 0))

              +-----------------------------+
    +---+     | +---+      +---+      +---+ |
    | 0 | --->| | 1 | ---> | 2 | ---> | 3 | |
    +---+     | +---+      +---+      +---+ |
              +-----------------------------+

2

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

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

আরও তথ্যের জন্য, দেখুন ক্লিন হোমপৃষ্ঠা এবং এই উইকিপিডিয়া নিবন্ধটি দেখুন

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