তুচ্ছ কীগুলির ক্ষেত্রে মানহীনকে unordered_map ব্যবহার করার কোনও সুবিধা আছে কি?


371

unordered_mapসি ++ এ সম্পর্কে একটি সাম্প্রতিক আলাপ আমাকে বুঝতে পেরেছিল যে আমি unordered_mapবেশিরভাগ ক্ষেত্রে যেখানে আমি mapআগে ব্যবহার করেছি সেগুলির জন্য ব্যবহার করা উচিত , কারণ দেখার দক্ষতা ( মোড়কৃত ও (1) বনাম ও (লগ এন) )। বেশিরভাগ সময় আমি কোনও মানচিত্র ব্যবহার করি, আমি হয় intবা std::stringমূল প্রকার হিসাবে ব্যবহার করি ; সুতরাং, হ্যাশ ফাংশনটির সংজ্ঞা নিয়ে আমার কোনও সমস্যা হয়নি। আমি এটির বিষয়ে যত বেশি চিন্তাভাবনা করেছি ততই আমি বুঝতে পেরেছি যে সহজ ধরণের কীগুলির ক্ষেত্রে আমি std::mapওভার এ ব্যবহার করার কোনও কারণ খুঁজে পাচ্ছি না std::unordered_map- আমি ইন্টারফেসগুলি একবার দেখেছি, এবং কোনও পাইনি উল্লেখযোগ্য পার্থক্য যা আমার কোডকে প্রভাবিত করবে।

অত: পর প্রশ্ন: সেখানে ব্যবহার করতে কোনো বাস্তব কারণ নেই std::mapওভার std::unordered_mapমত সহজ ধরনের ক্ষেত্রে intএবং std::string?

আমি কঠোরভাবে প্রোগ্রামিং দৃষ্টিকোণ থেকে জিজ্ঞাসা করছি - আমি জানি যে এটি পুরোপুরি মান হিসাবে বিবেচিত হয় না এবং এটি পোর্টিংয়ের ক্ষেত্রে সমস্যা তৈরি করতে পারে।

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

সম্পাদনা: দুহ, আমি স্পষ্টভাবে ভুলে গেছি (ধন্যবাদ জিএমান!) - হ্যাঁ, মানচিত্র অবশ্যই অর্ডার করা হয়েছে - আমি তা জানি, এবং অন্যান্য কারণগুলিও খুঁজছি।


22
আমি সাক্ষাত্কারে এই প্রশ্নটি জিজ্ঞাসা করতে চাই: "বুদ্বুদ-সাজানোর চেয়ে দ্রুত সাজানোর কখন ভাল?" প্রশ্নের উত্তর জটিলতার তত্ত্বের ব্যবহারিক প্রয়োগের অন্তর্দৃষ্টি দেয় এবং কেবল ও (1) এর মতো সরল কালো ও সাদা বিবৃতি ও (এন) বা ও (কে) ও (লগন) ইত্যাদির সমতুল্য নয় is ..

42
@ বেহ, আমার মনে হয় আপনি বোঝাতে চেয়েছিলেন "কখন দ্রুত-বাছাইয়ের চেয়ে বুদ্বুদ-সাজানো ভাল": পি
কর্নেল কিসেলিউইচজ

2
একটি স্মার্ট পয়েন্টার একটি তুচ্ছ কী হবে?
থমথম

: নিম্নলিখিত ক্ষেত্রে এই মানচিত্র সুবিধাজনক এক অন্যতম stackoverflow.com/questions/51964419/...
anilbey

উত্তর:


398

এটি ভুলে যাবেন না যে mapএটির উপাদানগুলি অর্ডার করে। যদি আপনি এটি ছেড়ে দিতে না পারেন, অবশ্যই আপনি ব্যবহার করতে পারবেন না unordered_map

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

সুতরাং, আপনার যদি খাঁটি অনুসন্ধান-পুনরুদ্ধারের প্রয়োজন হয় তবে আমি বলব যে unordered_mapউপায়। তবে সর্বদা ট্রেড-অফ রয়েছে এবং আপনি যদি তা সামর্থ্য না করেন তবে আপনি এটি ব্যবহার করতে পারবেন না।

কেবলমাত্র ব্যক্তিগত অভিজ্ঞতা থেকে, আমি প্রধান সত্তার চেহারাতে টেবিলের unordered_mapপরিবর্তে ব্যবহার করার সময় পারফরম্যান্সে (অবশ্যই পরিমাপ করা হয়েছে) এক বিরাট উন্নতি পেয়েছি map

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


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

4
আরএ: আপনার নিজের বরাদ্দকারী প্রকারের সাথে কোনও ধারককে সংযুক্ত করে আপনি কিছুটা নিয়ন্ত্রণ করতে পারেন, যদি আপনি মনে করেন এটি কোনও নির্দিষ্ট প্রোগ্রামের জন্য গুরুত্বপূর্ণ।

9
আপনি যদি আকারটি জানেন unordered_mapএবং শুরুতে এটি সংরক্ষণ করেন - আপনি কি এখনও অনেক সন্নিবেশের জরিমানা প্রদান করেন? বলুন, আপনি যখন অনুসন্ধান সারণীটি তৈরি করেছিলেন তখন আপনি কেবল একবার সন্নিবেশ করছিলেন - এবং পরে কেবলমাত্র এটি থেকে পড়বেন।
থমথম

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

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

126

আপনি যদি নিজের std::mapএবং std::unordered_mapবাস্তবায়নের গতি তুলনা করতে চান তবে আপনি গুগলের স্পার্স্যাশ প্রকল্প ব্যবহার করতে পারেন যা তাদের সময়সীমার জন্য একটি সময়_হ্যাশ_ম্যাপ রয়েছে। উদাহরণস্বরূপ, একটি x86_64 লিনাক্স সিস্টেমে gcc 4.4.2 সহ

$ ./time_hash_map
TR1 UNORDERED_MAP (4 byte objects, 10000000 iterations):
map_grow              126.1 ns  (27427396 hashes, 40000000 copies)  290.9 MB
map_predict/grow       67.4 ns  (10000000 hashes, 40000000 copies)  232.8 MB
map_replace            22.3 ns  (37427396 hashes, 40000000 copies)
map_fetch              16.3 ns  (37427396 hashes, 40000000 copies)
map_fetch_empty         9.8 ns  (10000000 hashes,        0 copies)
map_remove             49.1 ns  (37427396 hashes, 40000000 copies)
map_toggle             86.1 ns  (20000000 hashes, 40000000 copies)

STANDARD MAP (4 byte objects, 10000000 iterations):
map_grow              225.3 ns  (       0 hashes, 20000000 copies)  462.4 MB
map_predict/grow      225.1 ns  (       0 hashes, 20000000 copies)  462.6 MB
map_replace           151.2 ns  (       0 hashes, 20000000 copies)
map_fetch             156.0 ns  (       0 hashes, 20000000 copies)
map_fetch_empty         1.4 ns  (       0 hashes,        0 copies)
map_remove            141.0 ns  (       0 hashes, 20000000 copies)
map_toggle             67.3 ns  (       0 hashes, 20000000 copies)

2
দেখে মনে হচ্ছে অর্ডারযুক্ত মানচিত্রটি বেশিরভাগ ক্রিয়াকলাপে মানচিত্রটিকে আঘাত করে in সন্নিবেশের আগে ...
মাইকেল চতুর্থ

7
স্পর্শেহশের আর অস্তিত্ব নেই। এটি মুছে ফেলা বা নামানো হয়েছে।
ব্যবহারকারী 9102d82

1
@ User9102d82 আমি ওয়েবেব্যাকম্যাচিন লিঙ্কটি উল্লেখ করতে প্রশ্নটি সম্পাদনা করেছি ।
andreee

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

82

আমি জিএমএন প্রায় একই পয়েন্টটি প্রতিধ্বনিত করলাম: ব্যবহারের ধরণের উপর নির্ভর করে (ভিএস ২০০৮ এসপি 1 এ অন্তর্ভুক্ত বাস্তবায়ন ব্যবহারের std::mapচেয়ে) দ্রুত (এবং প্রায়শই হয়) হতে পারে std::tr1::unordered_map

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

বিপরীতে একটি শালীন হ্যাশ ফাংশন, সর্বদা পুরো কীটি দেখায় । আইওডাব্লু, এমনকি টেবিলের অনুসন্ধানের ক্ষেত্রে ধ্রুবক জটিলতা থাকলেও হ্যাশটিতে নিজেই মোটামুটি রৈখিক জটিলতা থাকে (যদিও কীটির দৈর্ঘ্যে, আইটেমের সংখ্যা নয়)। কী হিসাবে দীর্ঘ স্ট্রিং সহ, কোনও তার অনুসন্ধান শুরু করারstd::map আগেই একটি অনুসন্ধান শেষ unordered_mapকরতে পারে ।

দ্বিতীয়ত, যখন হ্যাশ টেবিল মাপ অনেকগুলি পন্থা আছে, তাদের অধিকাংশই চমত্কার ধীর - পয়েন্ট যে যদি না লুক-হয় যথেষ্ট সন্নিবেশ এবং মুছে দেওয়া চেয়ে বেশি ঘন ঘন, std :: মানচিত্র প্রায়ই যতো তাড়াতাড়ি হবে std::unordered_map

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

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


2
dynamic hashingটেকনিক্সের মাধ্যমে হ্যাশ পুনরায় আকার পরিবর্তন করতে পারে k। অবশ্যই, এর অর্থ হ'ল পরিবর্তনের সময় আপনাকে 2 টি আলাদা টেবিল সন্ধান করতে হবে ...
ম্যাথিউ এম।

2
"কী হিসাবে দীর্ঘ স্ট্রিংগুলির সাথে, একটি স্ট্যান্ড :: ম্যাপ কোনও অনুসন্ধানবিহীন_ম্যাপ এমনকি তার অনুসন্ধান শুরু করার আগেই অনুসন্ধান শেষ করবে।" - যদি সংগ্রহটিতে কীটি উপস্থিত না থাকে। যদি এটি উপস্থিত থাকে তবে অবশ্যই ম্যাচটি নিশ্চিত করার জন্য পুরো দৈর্ঘ্যের তুলনা করা দরকার। তবে তেমনিভাবে unordered_mapএকটি সম্পূর্ণ তুলনার সাথে একটি হ্যাশ ম্যাচটি নিশ্চিত করা দরকার, সুতরাং লকিং প্রক্রিয়াটির কোন অংশটি আপনি বৈপরীত্য করছেন তা নির্ভর করে।
স্টিভ জেসোপ

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

56

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

g++ -g -O3 --std=c++0x   -c -o stdtests.o stdtests.cpp
g++ -o stdtests stdtests.o
gmurphy@interloper:HashTests$ ./stdtests
# 1st number column is insert time, 2nd is fetch time
 ** Integer Keys ** 
 unordered:      137      15
   ordered:      168      81
 ** Random String Keys ** 
 unordered:       55      50
   ordered:       33      31
 ** Real Words Keys ** 
 unordered:      278      76
   ordered:      516     298

2
পরীক্ষার জন্য ধন্যবাদ। আমরা শব্দটি পরিমাপ করছি না তা নিশ্চিত করার জন্য আমি প্রতিটি অপারেশন করতে বহুবার এটি পরিবর্তন করেছিলাম (এবং মানচিত্রে 1 এর পরিবর্তে কাউন্টারটি sertedোকানো হয়েছে)। আমি এটিকে বিভিন্ন সংখ্যক কী (2 থেকে 1000) এবং ম্যাপে 100 ডলার পর্যন্ত কী std::mapদাবিয়েছি std::unordered_map, বিশেষত পূর্ণসংখ্যার কীগুলির জন্য কিন্তু 100 ডলার কীগুলি দেখে মনে হয় এটি এর প্রান্ত হারিয়ে ফেলে এবং std::unordered_mapজিততে শুরু করে। ইতিমধ্যে অর্ডার করা সিক্যুয়েন্সটি একটিতে সন্নিবেশ করা std::mapখুব খারাপ, আপনি এর খারাপ পরিস্থিতিটি পাবেন (ও (এন))।
আন্দ্রেয়াস ম্যাগনুসন

30

আমি কেবল এটি উল্লেখ করতে চাই ... অনেক ধরণের unordered_mapএস আছে।

দেখুন Wikipedia নিবন্ধটি হ্যাশ মানচিত্রে। কোন বাস্তবায়ন ব্যবহৃত হয়েছিল তার উপর নির্ভর করে চেহারা-সন্ধান, সন্নিবেশ এবং মুছে ফেলার শর্তাবলী বৈশিষ্ট্যগুলি বেশ উল্লেখযোগ্যভাবে পরিবর্তিত হতে পারে।

এবং এটিই আমাকে সবচেয়ে বেশি উদ্বেগজনক unordered_mapকরে এসটিএল যুক্ত করার সাথে সাথে : তাদের একটি নির্দিষ্ট বাস্তবায়ন বেছে নিতে হবে কারণ আমি সন্দেহ করি যে তারা Policyরাস্তায় নামবে, এবং তাই আমরা গড় ব্যবহারের জন্য একটি বাস্তবায়নে আটকে যাব এবং এর জন্য কিছুই নেই অন্যান্য ক্ষেত্রে ...

উদাহরণস্বরূপ কয়েকটি হ্যাশ মানচিত্রে লিনিয়ার রিহ্যাশিং রয়েছে, যেখানে পুরো হ্যাশ মানচিত্রটি একবারে পুনর্নির্মাণের পরিবর্তে প্রতিটি সন্নিবেশে একটি অংশ পুনরায় রিশ্যাশ করা হয়, যা ব্যয়কে পরিমাণমতো করতে সহায়তা করে।

অন্য উদাহরণ: কিছু হ্যাশ মানচিত্র বালতির জন্য নোডের একটি সহজ তালিকা ব্যবহার করে, অন্যরা একটি মানচিত্র ব্যবহার করে, অন্যরা নোড ব্যবহার করে না তবে নিকটতম স্লটটি খুঁজে পায় এবং শেষ পর্যন্ত কেউ নোডের একটি তালিকা ব্যবহার করে তবে এটি পুনরায় অর্ডার করে যাতে শেষ অ্যাক্সেস উপাদানটি থাকে সামনের দিকে (একটি ক্যাশিং জিনিস হিসাবে)।

তাই এই মুহুর্তে আমি পছন্দ করি std::map বা সম্ভবত একটি loki::AssocVector(হিমায়িত ডেটা সেটগুলির জন্য) পছন্দ করি।

আমাকে ভুল করবেন না, আমি std::unordered_mapভবিষ্যতেও ব্যবহার করতে চাই এবং আমি এটি ব্যবহার করতে চাই তবে আপনি যখন এটি প্রয়োগের সমস্ত উপায় এবং ফলাফলের বিভিন্ন পারফরম্যান্সের ফলস্বরূপ চিন্তা করেন তখন এ জাতীয় ধারকটির বহনযোগ্যতা "বিশ্বাস" করা কঠিন difficult এই এর.


17
+1: বৈধ পয়েন্ট - আমার নিজের প্রয়োগটি যখন ব্যবহার করা হয়েছিল তখন জীবন সহজ ছিল - কমপক্ষে আমি জানতাম কোথায় where এটি
স্তন্যপান হয়েছে

25

উল্লেখযোগ্য পার্থক্য যা এখানে যথাযথভাবে এখানে উল্লেখ করা হয়নি:

  • mapপুনরুক্তিকারীকে সমস্ত উপাদানগুলিতে স্থিতিশীল রাখে, সি ++ 17 এ আপনি mapপুনরুক্তিগুলি অকার্যকর না করেও তাদের উপাদানগুলিকে এক থেকে অন্যটিতে সরিয়ে নিতে পারেন (এবং যদি কোনও সম্ভাব্য বরাদ্দ ছাড়াই সঠিকভাবে প্রয়োগ করা হয়)।
  • map একক ক্রিয়াকলাপের সময়গুলি সাধারণত আরও সুসংগত হয় কারণ তাদের কখনও বড় বরাদ্দের প্রয়োজন হয় না।
  • unordered_mapব্যবহার std::hashআগে থেকে libstdc ++ বাস্তবায়িত যেমন করণীয় প্রবন হলে অবিশ্বস্ত ইনপুট দিয়ে খাওয়ানো (এটা একটি ধ্রুবক বীজ সঙ্গে MurmurHash2 ব্যবহার করে - না যে বীজবপন হবে সত্যিই সাহায্য দেখুন https://emboss.github.io/blog/2012/12/14/ ব্রেকিং-গুনগুন-হ্যাশ-বন্যা-ডস-রিলোড / )।
  • অর্ডার করা দক্ষ পরিসীমা অনুসন্ধানগুলি সক্ষম করে, উদাহরণস্বরূপ কী ≥ 42 দিয়ে সমস্ত উপাদানকে পুনরাবৃত্তি করতে পারে।

14

হ্যাশ টেবিলগুলিতে সাধারণ মানচিত্রের প্রয়োগের চেয়ে বেশি ধ্রুবক রয়েছে যা ছোট পাত্রে significant সর্বোচ্চ আকার 10, 100, বা এমনকি 1000 বা আরও বেশি হতে পারে? ধ্রুবকগুলি আগের মতোই তবে ও (লগ এন) ও (কে) এর কাছাকাছি। (মনে রাখবেন লোগারিথমিক জটিলতা এখনও সত্যই ভাল))

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

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


@ রোজার, আপনি কি এমন উপাদানগুলির আনুমানিক পরিমাণটি জানেন যা আনর্ডারড_ম্যাপ মানচিত্রটি বেস্ট করে? যাইহোক, আমি সম্ভবত এটির জন্য একটি পরীক্ষা লিখব ... (+1)
কর্নেল কিসিলেউইচজ

1
@ কর্নেল: এটি খুব বেশি লাগে না; আমার পরীক্ষাগুলি প্রায় 10,000 উপাদানগুলির সাথে ছিল। আমরা যদি সত্যই একটি সঠিক গ্রাফ চাই, আপনি নির্দিষ্ট প্ল্যাটফর্ম এবং নির্দিষ্ট ক্যাশে আকার সহ একটি বাস্তবায়ন mapএবং এর মধ্যে একটি দেখতে পারেন unordered_mapএবং একটি জটিল বিশ্লেষণ করতে পারেন। : পি
GManNickG

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

13

অন্যান্য উত্তরে কারণ দেওয়া হয়েছে; এখানে অন্য একটি।

স্ট্যান্ড :: মানচিত্র (ভারসাম্য বাইনারি ট্রি) ক্রিয়াকলাপগুলি মোড়কযুক্ত ও (লগ এন) এবং সবচেয়ে খারাপ ক্ষেত্রে ও (লগ এন)। std :: unordered_map (হ্যাশ টেবিল) ক্রিয়াকলাপগুলি amorised হে (1) এবং সবচেয়ে খারাপ ক্ষেত্রে O (n)।

এটি বাস্তবে কীভাবে সম্পাদিত হয় তা হ্যাশ টেবিলটি একবারে একবারে ও (এন) অপারেশন সহ "হিচাপগুলি" হয় যা আপনার অ্যাপ্লিকেশন সহ্য করতে পারে বা নাও পারে। এটি যদি এটি সহ্য করতে না পারে তবে আপনি STD :: মানচিত্রের চেয়ে বেশি পছন্দ করবেন :: বিনা বিভাগে_ম্যাপ।


12

সারসংক্ষেপ

অর্ডিং ধরে নেওয়া গুরুত্বপূর্ণ নয়:

  • আপনি যদি একবার বড় টেবিল তৈরি করতে চলেছেন এবং প্রচুর ক্যোয়ারী করেন তবে ব্যবহার করুন std::unordered_map
  • আপনি যদি ছোট টেবিল তৈরি করতে যাচ্ছেন (100 টি উপাদানগুলির নিচে হতে পারে) এবং প্রচুর প্রশ্নগুলি করেন তবে ব্যবহার করুন std::map। এটি কারণ এটি পড়তে হয়O(log n)
  • আপনি যদি টেবিলটি অনেকগুলি পরিবর্তন করতে যাচ্ছেন তবে তা হতে পারে std::map ভাল বিকল্প ।
  • আপনার যদি সন্দেহ হয় তবে কেবল ব্যবহার করুন std::unordered_map

ঐতিহাসিক প্রেক্ষাপট

বেশিরভাগ ভাষায়, সীমাহীন মানচিত্র (ওরফে হ্যাশ ভিত্তিক অভিধান) হ'ল ডিফল্ট মানচিত্র তবে সি ++ এ আপনি ডিফল্ট মানচিত্র হিসাবে আদেশযুক্ত মানচিত্র পাবেন। তা কীভাবে হল? কিছু লোক ভ্রান্তভাবে ধরে নিয়েছে যে সি ++ কমিটি তাদের অনন্য জ্ঞানের ভিত্তিতে এই সিদ্ধান্ত নিয়েছে তবে সত্যের চেয়ে সত্য দুর্ভাগ্যজনক।

এটি ব্যাপকভাবে বিশ্বাস করা হয় যে সি ++ ডিফল্ট হিসাবে অর্ডার করা মানচিত্রের সাথে শেষ হয়েছে কারণ কীভাবে সেগুলি প্রয়োগ করা যেতে পারে সে সম্পর্কে খুব বেশি পরামিতি নেই। অন্যদিকে, হ্যাশ ভিত্তিক বাস্তবায়নের মধ্যে অনেক কথা বলা উচিত। সুতরাং মানীকরণে গ্রিডলকগুলি এড়াতে তারা কেবল অর্ডার করা মানচিত্রের সাথে পেয়েছে । ২০০৫ সালের দিকে, অনেকগুলি ভাষা ইতিমধ্যে হ্যাশ ভিত্তিক প্রয়োগের ভাল প্রয়োগ করেছে এবং তাই কমিটির পক্ষে নতুন গ্রহণ করা আরও সহজ হয়েছিল std::unordered_map। একটি নিখুঁত বিশ্বে, std::mapআনর্ডারড হত এবং আমাদের std::ordered_mapআলাদা আলাদা টাইপ থাকত ।

কর্মক্ষমতা

দুটি গ্রাফের নীচে তাদের জন্য কথা বলা উচিত ( উত্স ):

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন


আকর্ষণীয় তথ্য; আপনার পরীক্ষায় আপনি কতগুলি প্ল্যাটফর্ম অন্তর্ভুক্ত করেছিলেন?
টবি স্পিড

1
আপনার এখানে পোস্ট করা ২ টি চিত্র অনুসারে স্টাড :: আনর্ডার্ড_ম্যাপ সর্বদা স্টাড :: মানচিত্রের চেয়ে আরও ভাল সম্পাদন করে কেন ছোট টেবিলের জন্য আমাকে স্ট্যান্ড :: ম্যাপ ব্যবহার করা উচিত?
রিকি

গ্রাফ 0.13 এম বা আরও বেশি উপাদানের জন্য কর্মক্ষমতা দেখায়। আপনার যদি ছোট (হতে পারে <100) উপাদান থাকে তবে ও (লগ এন) আনর্ডারড মানচিত্রের চেয়ে ছোট হতে পারে।
শীতল শাহ

10

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

জন্য mapবাস্তবায়ন, এটা কাজ শেষ 200 MS লাগে। জন্য unordered_map+ + map, এটি জন্য 70 MS লাগে unordered_mapসন্নিবেশ এবং জন্য 80 MS mapসন্নিবেশ। সুতরাং হাইব্রিড বাস্তবায়ন 50 এমএস দ্রুত।

আমরা এটি ব্যবহার করার আগে আমাদের দুবার চিন্তা করা উচিত map। আপনার প্রোগ্রামের চূড়ান্ত ফলাফলের জন্য যদি কেবলমাত্র ডেটা বাছাই করার প্রয়োজন হয় তবে একটি হাইব্রিড সমাধান আরও ভাল হতে পারে।


0

উপরের সমস্তটির সাথে সামান্য সংযোজন:

আরও ভাল ব্যবহারের mapসময় যখন আপনার উপাদানগুলি পরিসীমা অনুসারে পাওয়ার দরকার হয় সেগুলি সাজানো হয় এবং আপনি কেবল একটি সীমানা থেকে অন্য সীমানায় পুনরাবৃত্তি করতে পারেন।


-1

থেকে: http://www.cplusplus.com/references/map/map/

"অভ্যন্তরীণভাবে, কোনও মানচিত্রের উপাদানগুলি সর্বদা তার কী দ্বারা বাছাই করা হয় তার অভ্যন্তরীণ তুলনামূলক অবজেক্টের (তুলনা প্রকারের) দ্বারা নির্দেশিত নির্দিষ্ট কঠোর দুর্বল আদেশ মানদণ্ড অনুসরণ করে always

মানচিত্রের পাতাগুলি তাদের কী দ্বারা পৃথক উপাদানগুলিতে অ্যাক্সেস করার জন্য আনর্ডারড_ম্যাপ কনটেইনারগুলির তুলনায় সাধারণত ধীর হয় তবে তারা তাদের আদেশের ভিত্তিতে সাবসেটগুলিতে সরাসরি পুনরাবৃত্তির অনুমতি দেয়। "

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