হাস্কেল: তালিকা, অ্যারে, ভেক্টর, সিকোয়েন্সস


230

আমি হাস্কেল শিখছি এবং হাস্কেল তালিকার পারফরম্যান্স পার্থক্য এবং (আপনার ভাষা inোকান) এর অ্যারে সম্পর্কিত কয়েকটি নিবন্ধ পড়ছি।

একজন শিক্ষার্থী হয়ে আমি পারফরম্যান্সের পার্থক্যের কথা চিন্তা না করে কেবলমাত্র তালিকা ব্যবহার করি। আমি সম্প্রতি তদন্ত শুরু করেছি এবং হাস্কেলের মধ্যে প্রচুর ডেটা স্ট্রাকচার লাইব্রেরি উপলব্ধ available

ডেটা স্ট্রাকচারের কম্পিউটার বিজ্ঞানের তত্ত্বের খুব গভীরভাবে না গিয়ে কেউ দয়া করে তালিকা, অ্যারে, ভেক্টর, সিকোয়েন্সগুলির মধ্যে পার্থক্যটি ব্যাখ্যা করতে পারেন?

এছাড়াও, এমন কি কিছু সাধারণ নিদর্শন রয়েছে যেখানে আপনি অন্যের পরিবর্তে একটি ডেটা স্ট্রাকচার ব্যবহার করবেন?

ডেটা স্ট্রাকচারের অন্য কোনও রূপ রয়েছে যা আমি অনুপস্থিত এবং দরকারী হতে পারে?


1
তালিকা বনাম অ্যারে সম্পর্কে এই উত্তরটি একবার দেখুন: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / ১৯৯66666767/ / ভাস্কেল- অ্যারেজ- ভিএসস- লিস্টস ভেক্টরগুলির বেশিরভাগই অ্যারে হিসাবে একই রকম পারফরম্যান্স রয়েছে তবে একটি বৃহত এপিআই রয়েছে।
গ্রিজগোর্জ চুপাপা

ডেটা.ম্যাপটি এখানে খুব আলোচিত দেখে ভাল লাগবে। এটি বিশেষত বহুমাত্রিক ডেটার জন্য একটি দরকারী ডেটা কাঠামোর মতো বলে মনে হচ্ছে।
মার্টিন ক্যাপোডিসি

উত্তর:


339

তালিকা রক

হাস্কেলের সিক্যুয়াল ডেটাগুলির জন্য এখন পর্যন্ত সর্বাধিক বন্ধুত্বপূর্ণ ডেটা কাঠামো হ'ল তালিকা

 data [a] = a:[a] | []

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

ones :: [Integer]
ones = 1:ones

twos = map (+1) ones

tenTwos = take 10 twos

আশ্চর্য কাজ। অসীম ডেটা স্ট্রাকচার শিলা।

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

অন্য দিকে

তালিকাগুলির সাথে প্রথম সমস্যাটি হ'ল (!!)এগুলির মধ্যে সূচী করতে ϴ (কে) সময় লাগে যা বিরক্তিকর। এছাড়াও, সংযোজনগুলি ধীর হতে পারে ++, তবে হাস্কেলের অলস মূল্যায়ন মডেলটির অর্থ হল যে এগুলি যদি কিছু ঘটে তবে এগুলিকে সম্পূর্ণরূপে স্বতন্ত্র হিসাবে বিবেচনা করা যেতে পারে।

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

তালিকাগুলি সহ তৃতীয় সমস্যাটি হ'ল তাদের স্থানের দক্ষতা কম রয়েছে। অতিরিক্ত পয়েন্টারগুলির গোছাগুলি আপনার স্টোরেজটিকে ধ্রুব করে (ধ্রুবক ফ্যাক্টর দ্বারা)।

সিকোয়েন্সগুলি কার্যকরী

Data.Sequenceঅভ্যন্তরীণভাবে আঙ্গুলের গাছের উপর ভিত্তি করে (আমি জানি, আপনি এটি জানতে চান না) যার অর্থ তাদের কিছু দুর্দান্ত বৈশিষ্ট্য রয়েছে

  1. খাঁটি কার্যকর। Data.Sequenceসম্পূর্ণরূপে প্রতিরোধী ডেটা স্ট্রাকচার।
  2. গাছের শুরু এবং শেষের দিকে দ্রুত অ্যাক্সেসের ভয় করুন। প্রথম বা শেষ উপাদানটি পেতে বা গাছ সংযোজন করার জন্য ϴ (1) (মোড়িত) জিনিসগুলির তালিকাগুলি দ্রুততম, Data.Sequenceবেশিরভাগ ধীরে ধীরে ধীর।
  3. Log (লগ এন) অনুক্রমের মাঝখানে অ্যাক্সেস। এর মধ্যে নতুন সিকোয়েন্সগুলি তৈরি করতে মান সন্নিবেশ অন্তর্ভুক্ত রয়েছে
  4. উচ্চমানের এপিআই

অন্যদিকে, Data.Sequenceডেটা লোকালিটি সমস্যার জন্য খুব বেশি কিছু করে না এবং কেবল সীমাবদ্ধ সংগ্রহের জন্য কাজ করে (এটি তালিকার তুলনায় কম অলস)

অ্যারেগুলি মূর্খতার জন্য নয়

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

ভেক্টর একটি "আরও ভাল" অ্যারে

Data.Vectorপ্যাকেজ একটি উচ্চ স্তরের এবং ক্লিনার API এ অ্যারে উদারতা সব না। আপনি কী করছেন তা আপনি যদি না জানেন তবে আপনার যদি পারফরম্যান্সের মতো অ্যারে প্রয়োজন হয় তবে আপনার এগুলি ব্যবহার করা উচিত। অবশ্যই, কিছু সতর্কতামূলক প্রয়োগ এখনও রয়েছে - ডেটা স্ট্রাকচারের মতো পরিবর্তনীয় অ্যারে খাঁটি অলস ভাষায় খুব ভাল খেলেন না। তবুও, কখনও কখনও আপনি যে ও (1) পারফরম্যান্স চান এবং Data.Vectorএটি আপনাকে ব্যবহারযোগ্য প্যাকেজে দেয়।

আপনার কাছে অন্যান্য বিকল্প রয়েছে

আপনি যদি শেষে দক্ষতার সাথে সন্নিবেশ করার ক্ষমতা সহ তালিকাগুলি চান তবে আপনি একটি পার্থক্য তালিকা ব্যবহার করতে পারেন । পারফরম্যান্স স্ক্রু করার তালিকার সেরা উদাহরণটি আসে [Char]যা থেকে উপস্থাপনাটি আলাদা হয় StringCharতালিকাগুলি বিশ্বাসযোগ্য, তবে সি স্ট্রিংয়ের চেয়ে 20 গুণ ধীর গতিতে চালানোর ঝোঁক রয়েছে, তাই নির্দ্বিধায় Data.Textবা খুব দ্রুত নির্বিঘ্নে অনুভব করুন Data.ByteString। আমি নিশ্চিত যে অন্যান্য সিকোয়েন্স ভিত্তিক গ্রন্থাগারগুলি আমি এখনই ভাবছি না।

উপসংহার

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

Prelude.map                --->  Prelude.fmap (works for every Functor)
Prelude.foldr/foldl/etc    --->  Data.Foldable.foldr/foldl/etc
Prelude.sequence           --->  Data.Traversable.sequence
etc

আসলে, Data.Traversableএমন একটি এপিআই সংজ্ঞায়িত করে যা কোনও কিছুতেই "তালিকান" তালিকায় কম বেশি সর্বজনীন।

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


সম্পাদনা: মন্তব্যের উপর ভিত্তি করে আমি বুঝতে পারি কখন কখন Data.Vectorবনাম ব্যবহার করব তা আমি কখনই ব্যাখ্যা করি নি Data.Sequence। অ্যারে এবং ভেক্টরগুলি অত্যন্ত দ্রুত ইনডেক্সিং এবং স্লাইসিং অপারেশন সরবরাহ করে তবে মূলত ক্ষণস্থায়ী (আবশ্যক) ডেটা স্ট্রাকচার। বিশুদ্ধ কার্মিক ডাটা স্ট্রাকচার মত Data.Sequenceএবং []দক্ষতার উপস্থিত করুক নতুন পুরাতন মান থেকে মান যেন আপনি পুরানো মান পরিবর্তিত করেছিল।

  newList oldList = 7 : drop 5 oldList

পুরানো তালিকাটি পরিবর্তন করে না, এবং এটি অনুলিপি করতে হবে না। সুতরাং oldListঅবিশ্বাস্যভাবে দীর্ঘ হলেও , এই "পরিবর্তন" খুব দ্রুত হবে। একভাবে

  newSequence newValue oldSequence = Sequence.update 3000 newValue oldSequence 

newValueএর 3000 উপাদানটির জায়গায় একটি সহ একটি নতুন সিক্যুয়েন্স তৈরি করবে । আবার এটি পুরানো ক্রমটি ধ্বংস করে না, এটি কেবল একটি নতুন তৈরি করে। তবে, এটি খুব দক্ষতার সাথে এটি করে, ও (লগ (মিনিট (কে, ন)) গ্রহণ করে যেখানে এন সিকোয়েন্সটির দৈর্ঘ্য, এবং কে হল সূচকটি যা আপনি সংশোধন করেন।

আপনি সহজেই Vectorsএবং এর সাথে এটি করতে পারবেন না Arrays। এগুলি সংশোধন করা যায় তবে এটি আসল অপরিহার্য পরিবর্তন, এবং তাই নিয়মিত হাস্কেল কোডে করা যায় না। এর অর্থ Vectorপ্যাকেজে থাকা ক্রিয়াকলাপগুলি যা পরিবর্তনের মতো করে snocএবং consপুরো ভেক্টরকে অনুলিপি করতে হয় তাই O(n)সময় নেয়। এর একমাত্র ব্যতিক্রম হ'ল আপনি মোনাডের (বা ) Vector.Mutableঅভ্যন্তরে পরিবর্তনীয় সংস্করণ ( ) ব্যবহার করতে পারেন এবং আপনার সমস্ত পরিবর্তনগুলি ঠিক যেমন একটি অত্যাবশ্যক ভাষায় করতে পারেন তেমন করতে পারেন । আপনি যখন সম্পন্ন হয়ে যান, আপনি খাঁটি কোডের সাথে ব্যবহার করতে চান এমন পরিবর্তনীয় কাঠামোয় পরিণত করতে আপনি আপনার ভেক্টরকে "হিমায়িত" করেন। STIO

আমার অনুভূতিটি হ'ল Data.Sequenceযদি কোনও তালিকা যথাযথ না হয় তবে আপনাকে ডিফল্ট করা উচিত । ব্যবহারের Data.Vectorশুধুমাত্র আপনার ব্যবহারের প্যাটার্ন অনেক পরিবর্তন উপার্জন জড়িত যদি না, অথবা যদি আপনি এসটি / আই monads মধ্যে অত্যন্ত উচ্চ কার্যকারিতা প্রয়োজন।

যদি STমোনাদের এই সমস্ত আলোচনা আপনাকে বিভ্রান্ত করে চলেছে: খাঁটি দ্রুত এবং সুন্দরকে আঁকড়ে থাকার আরও আরও কারণ Data.Sequence


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

21
দুর্দান্ত উত্তর। আমার একমাত্র অভিযোগ হ'ল "সিকোয়েন্সগুলি ক্রিয়ামূলক" তাদের কিছুটা নীচে ফেলেছে। সিকোয়েন্সগুলি কার্যকরী দুর্দান্ত aw তাদের কাছে অন্য একটি বোনাস দ্রুত যোগদান এবং বিভাজন (লগ এন) is
ড্যান বার্টন

3
@ ড্যানবার্টন মেলা আমি সম্ভবত আন্ডারলেল করেছি Data.Sequence। ফিঙ্গার গাছগুলি কম্পিউটিংয়ের ইতিহাসের অন্যতম দুর্দান্ত উদ্ভাবন (গুইবাস সম্ভবত কোনওদিন টিউরিং অ্যাওয়ার্ড পাওয়া উচিত) এবং Data.Sequenceএটি একটি দুর্দান্ত বাস্তবায়ন এবং এটির একটি খুব ব্যবহারযোগ্য এপিআই রয়েছে।
ফিলিপ জেএফ

3
জবর বাক্যে কথন, "UseData.Vector শুধুমাত্র আপনার ব্যবহারের প্যাটার্ন অনেক পরিবর্তন উপার্জন জড়িত যদি না, অথবা যদি আপনি এসটি / আই monads মধ্যে অত্যন্ত উচ্চ কার্যকারিতা প্রয়োজন .." কারণ যদি আপনি হয় অনেক পরিবর্তন উপার্জন (বারবার মত (100 কিলোবাইট বার) বিকশিত 100 ক উপাদান), তারপরে গ্রহণযোগ্য পারফরম্যান্স পেতে আপনার প্রয়োজন এসটি / আইও ভেক্টর,
মিস্টারবি

4
(খাঁটি) ভেক্টর এবং অনুলিপি সম্পর্কে উদ্বেগগুলি আংশিকভাবে স্ট্রিম ফিউশন দ্বারা হ্রাস করা হয়েছে, উদাহরণস্বরূপ: import qualified Data.Vector.Unboxed as VU; main = print (VU.cons 'a' (VU.replicate 100 'b'))কোরে 404 বাইট (101 টি চর) এর একক বরাদ্দকে সংকলন করে: hpaste.org/65015
ফ্যান্টাকরসালাদ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.