জাভা হ্যাশম্যাপের পারফরম্যান্স অপটিমাইজেশন / বিকল্প


102

আমি একটি বড় হ্যাশম্যাপ তৈরি করতে চাই তবে put()পারফরম্যান্সটি যথেষ্ট ভাল নয়। কোন ধারনা?

অন্যান্য ডেটা কাঠামোর পরামর্শগুলি স্বাগত তবে আমার একটি জাভা মানচিত্রের চেহারা বৈশিষ্ট্যটি প্রয়োজন:

map.get(key)

আমার ক্ষেত্রে আমি 26 মিলিয়ন এন্ট্রি সহ একটি মানচিত্র তৈরি করতে চাই। স্ট্যান্ডার্ড জাভা হ্যাশম্যাপ ব্যবহার করে পুট রেট 2-3 মিলিয়ন সন্নিবেশের পরে অসহনীয়ভাবে ধীর হয়ে যায়।

এছাড়াও, কীগুলির জন্য বিভিন্ন হ্যাশ কোড বিতরণ ব্যবহার করা সাহায্য করতে পারে তা কি কেউ জানেন?

আমার হ্যাশকোড পদ্ধতি:

byte[] a = new byte[2];
byte[] b = new byte[3];
...

public int hashCode() {
    int hash = 503;
    hash = hash * 5381 + (a[0] + a[1]);
    hash = hash * 5381 + (b[0] + b[1] + b[2]);
    return hash;
}

সমান বস্তুগুলির একই হ্যাশকোড রয়েছে তা নিশ্চিত করতে আমি সংযোজনের সংস্থানমূলক সম্পত্তি ব্যবহার করছি। অ্যারেগুলি 0 - 51 সীমাতে মান সহ বাইট হয় Values ​​মানগুলি কেবল দুটি অ্যারেতে একবার ব্যবহৃত হয়। অ্যারেগুলিতে সমান হয় যদি অ্যারেতে একই মান থাকে (উভয় ক্রমে) এবং বি অ্যারেতে একই হয়। সুতরাং a = {0,1} b = {45,12,33। এবং a = {1,0} b = {33,45,12। সমান।

সম্পাদনা করুন, কিছু নোট:

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

  • ডিফল্ট জাভা হ্যাশম্যাপের প্রাথমিক ক্ষমতাটি 26 মিলিয়নে সেট করা কর্মক্ষমতা হ্রাস করে।

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


29
যদি হ্যাশম্যাপ ধীর হয়ে যায়, সমস্ত সম্ভাবনায় আপনার হ্যাশ ফাংশনটি যথেষ্ট ভাল নয়।
পাস্কেল কুয়াক

12
ডাক্তার, এটি ব্যাথা যখন আমি কি এই
skaffman

12
এই সত্যিই একটি ভাল প্রশ্ন; হ্যাশিংয়ের অ্যালগরিদমগুলি কেন গুরুত্বপূর্ণ এবং তারা পারফরম্যান্সে কী প্রভাব ফেলতে পারে তার একটি দুর্দান্ত বিক্ষোভ
অক্সবো_লাক

12
এর এর যোগফলের দৈর্ঘ্য 0 থেকে 102 এবং বি এর যোগফল 0 থেকে 153 এর ব্যাপ্তি রয়েছে সুতরাং আপনার কেবলমাত্র 15,606 সম্ভাব্য হ্যাশ মান এবং একই হ্যাশকোড সহ গড়ে 1,666 কী রয়েছে। আপনার হ্যাশকোডটি পরিবর্তন করা উচিত যাতে সম্ভব হ্যাশকোডগুলির সংখ্যা কীগুলির সংখ্যার চেয়ে অনেক বেশি।
পিটার লরি

6
আমি মানসিকভাবে এই সিদ্ধান্তে পৌঁছেছি আপনি টেক্সাস হোল্ড 'em জুজু ;-) মডেলিং করছি
bacar

উত্তর:


56

যেহেতু অনেকে নির্দেশ করেছিলেন hashCode()পদ্ধতিটিকে দোষ দেওয়া হয়েছিল। এটি কেবলমাত্র 26 মিলিয়ন স্বতন্ত্র বস্তুর জন্য প্রায় 20,000 কোড তৈরি করেছিল। এটি হ্যাশ বালতিতে গড়ে 1,300 অবজেক্ট = খুব খুব খারাপ। তবে আমি যদি 52 টি বেসকে একটি সংখ্যায় পরিণত করি তবে আমি প্রতিটি জিনিসের জন্য একটি অনন্য হ্যাশ কোড পাওয়ার গ্যারান্টিযুক্ত:

public int hashCode() {       
    // assume that both a and b are sorted       
    return a[0] + powerOf52(a[1], 1) + powerOf52(b[0], 2) + powerOf52(b[1], 3) + powerOf52(b[2], 4);
}

public static int powerOf52(byte b, int power) {
    int result = b;
    for (int i = 0; i < power; i++) {
        result *= 52;
    }
    return result;
}

এই পদ্ধতিগুলি hashCode()চুক্তিটি সম্পূর্ণ করে তা নিশ্চিত করার জন্য অ্যারে বাছাই করা হয় যে সমান বস্তুগুলির একই হ্যাশ কোড রয়েছে। পুরানো পদ্ধতিটি ব্যবহার করে প্রতি সেকেন্ডে 100,000 পুট, 100,000 থেকে 2,000,000 ব্লকের ওপরে প্রতি সেকেন্ডে পুটের সংখ্যা ছিল:

168350.17
109409.195
81344.91
64319.023
53780.79
45931.258
39680.29
34972.676
31354.514
28343.062
25562.371
23850.695
22299.22
20998.006
19797.799
18702.951
17702.434
16832.182
16084.52
15353.083

নতুন পদ্ধতি ব্যবহার করে দেয়:

337837.84
337268.12
337078.66
336983.97
313873.2
317460.3
317748.5
320000.0
309704.06
310752.03
312944.5
265780.75
275540.5
264350.44
273522.97
270910.94
279008.7
276285.5
283455.16
289603.25

আরও অনেক ভাল। পুরানো পদ্ধতিটি খুব তাড়াতাড়ি বন্ধ করা হয়েছে যখন নতুনটি একটি ভাল থ্রুপুট রাখে।


17
আমি hashCodeপদ্ধতিতে অ্যারেগুলিকে সংশোধন না করার পরামর্শ দিচ্ছি । কনভেনশন দ্বারা, hashCodeবস্তুর অবস্থা পরিবর্তন করে না। সম্ভবত নির্মাতা তাদের বাছাই করার জন্য আরও ভাল জায়গা হবে।
মাইকেল ময়র্স

আমি সম্মত হলাম যে অ্যারে বাছাই করা উচিত কনস্ট্রাক্টরে। প্রদর্শিত কোডটি কখনও হ্যাশকোড সেট করে নি বলে মনে হচ্ছে। কোড গণনা করা হচ্ছে নিম্নরূপ সহজ করা সম্ভব: int result = a[0]; result = result * 52 + a[1]; //etc
আরএসপি

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

3
দ্রষ্টব্য আপনি হ্যাশকোডকেও ক্যাশে করতে পারেন (এবং যদি আপনার অবজেক্টটি পরিবর্তনীয় হয় তবে যথাযথভাবে অবৈধ করুন)।
NateS

1
শুধু java.util.Arrays.hashCode () ব্যবহার করুন । এটি সহজ (নিজের দ্বারা লেখার এবং বজায় রাখার জন্য কোনও কোড নেই), এর গণনাটি সম্ভবত দ্রুত (কম গুণ), এবং এর হ্যাশ কোডগুলির বিতরণ সম্ভবত আরও বেশি হবে।
জ্যাকসাহ্নওয়াল্ড্ট মনিকা পুনরায় ইনস্টল করুন

18

একটা জিনিষ আমি তোমার মধ্যে লক্ষ্য hashCode()পদ্ধতি যা অ্যারে উপাদানের ক্রম হল a[]এবং b[]গুরুত্ব নেই। সুতরাং (a[]={1,2,3}, b[]={99,100})হিসাবে একই মান হ্যাশ হবে (a[]={3,1,2}, b[]={100,99})। আসলে সমস্ত কী k1এবং k2কোথায় sum(k1.a)==sum(k2.a)এবং sum(k1.b)=sum(k2.b)সংঘর্ষের ফলস্বরূপ। আমি অ্যারের প্রতিটি অবস্থানে একটি ওজন নির্ধারণ করার পরামর্শ দিই:

hash = hash * 5381 + (c0*a[0] + c1*a[1]);
hash = hash * 5381 + (c0*b[0] + c1*b[1] + c3*b[2]);

যেখানে, c0, c1এবং c3হয় স্বতন্ত্র ধ্রুবক (আপনি বিভিন্ন ধ্রুবক ব্যবহার করতে পারেন bপ্রয়োজন হলে)। এটি আরও কিছু জিনিস আউট করা উচিত।


যদিও আমার এটিও যুক্ত করা উচিত যে এটি আমার পক্ষে কার্যকর হবে না কারণ আমি সেই সম্পত্তিটি চাই যা বিভিন্ন উপাদানগুলিতে একই উপাদানগুলির সাথে একই হ্যাশকোড দেয় want
ন্যাশ

5
সেক্ষেত্রে আপনার 52C2 + 52C3 হ্যাশকোড রয়েছে (আমার ক্যালকুলেটর অনুসারে 23426), এবং একটি হ্যাশম্যাপটি কাজের জন্য খুব ভুল সরঞ্জাম।
কেডিগ্রিগরি

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

7
@ অস্কার - আরও সংঘর্ষের কাজ আরও বেশি কাজের সমান , কারণ এখন আপনাকে হ্যাশ চেইনের একটি রৈখিক অনুসন্ধান করতে হবে। আপনার যদি সমান () এর জন্য 26,000,000 স্বতন্ত্র মান থাকে এবং হ্যাশকোড () প্রতি 26,000 স্বতন্ত্র মান থাকে তবে বালতি চেইনের প্রতিটিতে 1,000 টি অবজেক্ট থাকবে।
কেডিগ্রিগরি

@ ন্যাশ ০: আপনি বলে চলেছেন যে আপনি এগুলি একই হ্যাশকোড রাখতে চান তবে একই সাথে সমান হবেন না (সমান () পদ্ধতি দ্বারা সংজ্ঞায়িত)। কেন আপনি এটি চান?
এমএকে

17

পাসকালের বিশদ বিবরণ: আপনি কি বুঝতে পারছেন যে একটি হ্যাশম্যাপ কীভাবে কাজ করে? আপনার হ্যাশ টেবিলটিতে আপনার কয়েকটি সংখ্যক স্লট রয়েছে। প্রতিটি কীটির জন্য হ্যাশ মানটি পাওয়া যায় এবং তারপরে টেবিলে প্রবেশের জন্য ম্যাপ করা হয়। যদি দুটি হ্যাশ মানচিত্রে একই প্রবেশে মানচিত্র দেয় - একটি "হ্যাশের সংঘর্ষ" - হ্যাশম্যাপ একটি লিঙ্কযুক্ত তালিকা তৈরি করে।

হ্যাশ সংঘর্ষগুলি হ্যাশ মানচিত্রের পারফরম্যান্সকে হত্যা করতে পারে। চরম ক্ষেত্রে, যদি আপনার সমস্ত কীতে একই হ্যাশ কোড থাকে, বা তাদের বিভিন্ন হ্যাশ কোড রয়েছে তবে সেগুলি একই স্লটে মানচিত্র রাখে, তবে আপনার হ্যাশ মানচিত্রটি একটি লিঙ্কযুক্ত তালিকায় পরিণত হবে।

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

সম্পাদনা: আমার যোগ করা উচিত: আপনি যখনই একটি নতুন এন্ট্রি যুক্ত করবেন, ততবার হ্যাশম্যাপ পরীক্ষা করে এটি যদি নকল হয়। যখন একটি হ্যাশ সংঘর্ষ হয়, তখন সেই স্লটে ম্যাপ করা প্রতিটি কীগুলির সাথে আগত কীটিকে তুলনা করতে হবে। সুতরাং সবচেয়ে খারাপ ক্ষেত্রে যেখানে সবকিছু একটি একক স্লটে হ্যাশ করে, দ্বিতীয় কীটিকে প্রথম কীটির সাথে তুলনা করা হয়, তৃতীয় কীটি # 1 এবং # 2 এর সাথে তুলনা করা হয়, চতুর্থ কীটি # 1, # 2 এবং # 3 এর সাথে তুলনা করা হয় ইত্যাদি। আপনি কী # 1 মিলিয়নে পৌঁছানোর সময় পর্যন্ত আপনি একটি ট্রিলিয়ন তুলনা করে শেষ করেছেন।

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

তবে যাইহোক, এটি "পুরো পয়েন্ট" কে প্রভাবিত করে না যা আমি তৈরি করার চেষ্টা করছিলাম: যখন আপনার কাছে দুটি কী রয়েছে - হ্যাঁ, বিভিন্ন কীগুলি আবার একই কীটি প্রদর্শিত হবে না - সেই মানচিত্রটি টেবিলের একই স্লটে থাকবে , হ্যাশম্যাপ একটি লিঙ্কযুক্ত তালিকা তৈরি করে। তারপরে, এটি প্রকৃতপক্ষে কোনও বিদ্যমান কীটির সদৃশ কিনা তা দেখতে প্রতিটি নতুন কী পরীক্ষা করতে হবে, এই একই স্লটে মানচিত্রে একটি নতুন এন্ট্রি যুক্ত করার প্রতিটি প্রয়াস অবশ্যই প্রতিটি বিদ্যমান এন্ট্রি পরীক্ষা করে লিঙ্কযুক্ত তালিকাকে তাড়া করতে হবে এটি দেখার জন্য পূর্বের দেখা কীটির একটি সদৃশ বা এটি যদি নতুন কী হয়।

মূল পোস্টের অনেক পরে আপডেট করুন

আমি পোস্ট করার 6 বছর পরে এই উত্তরের সবেমাত্র একটি আপ-ভোট পেয়েছি যা আমাকে পুনরায় প্রশ্নটি পড়তে বাধ্য করেছিল।

প্রশ্নে দেওয়া হ্যাশ ফাংশন 26 মিলিয়ন এন্ট্রিগুলির জন্য ভাল হ্যাশ নয়।

এটি এক [0] + a [1] এবং খ [0] + বি [1] + বি [2] কে একসাথে যুক্ত করে। তিনি বলেন যে প্রতিটি বাইটের মান 0 থেকে 51 এর মধ্যে থাকে, সুতরাং এটি কেবল (51 * 2 + 1) * (51 * 3 + 1) = 15,862 সম্ভাব্য হ্যাশ মান দেয়। 26 মিলিয়ন এন্ট্রি সহ, এর অর্থ হ্যাশ মূল্য প্রতি গড়ে প্রায় 1639 এন্ট্রি। এটি প্রচুর সংঘর্ষ এবং সংযুক্ত তালিকার মাধ্যমে প্রচুর ক্রমিক অনুসন্ধানের প্রয়োজন requ

ওপি বলেছে যে অ্যারে এবং অ্যারে বি এর মধ্যে বিভিন্ন অর্ডার সমান হিসাবে বিবেচনা করা উচিত, [[[1,2], [3,4,5]]। সমান ([[২,১], [৫,৩,৪]] ]), এবং তাই চুক্তিটি সম্পাদন করতে তাদের অবশ্যই সমান হ্যাশ কোড থাকতে হবে। ঠিক আছে. তবুও, 15,000 এর চেয়ে বেশি সম্ভাব্য মান রয়েছে। তার দ্বিতীয় প্রস্তাবিত হ্যাশ ফাংশনটি আরও ভাল, একটি বিস্তৃত পরিসর দেয়।

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

return a[0]+a[1]*52+b[0]*52*52+b[1]*52*52*52+b[2]*52*52*52*52;

যা সংকলনের সময় সংকলক একবার গণনা সম্পাদন করে; বা ক্লাসে সংজ্ঞায়িত 4 টি স্ট্যাটিক ধ্রুবক রয়েছে।

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


3
হ্যাঁ, একটি খারাপ হ্যাশ ক্রিয়াকলাপের ফলে এই জাতীয় আচরণ হতে পারে। +1
হেনিং

আসলে তা না. তালিকা তৈরি করা হয় শুধুমাত্র যদি হ্যাশ একই, কিন্তু চাবিকাঠি বিভিন্ন । উদাহরণস্বরূপ যদি কোনও স্ট্রিং হ্যাশকোড 2345 দেয় এবং পূর্ণসংখ্যা একই হ্যাশকোডকে 2345 দেয় তবে পূর্ণসংখ্যাটি তালিকায় sertedোকানো হয় কারণ String.equals( Integer )এটি falseতবে আপনার যদি একই শ্রেণি থাকে (বা কমপক্ষে .equalsসত্য হয়) তবে একই প্রবেশিকা ব্যবহার করা হয়। উদাহরণস্বরূপ new String("one")এবং as নতুন স্ট্রিং ("এক") কী হিসাবে ব্যবহৃত, একই প্রবেশিকা ব্যবহার করবে। আসলে এই হল গোটা প্রথম স্থানে HashMap বিন্দু! নিজের জন্য দেখুন: পেস্টবিন.
com

3
@ অস্কার: আমার উত্তরটি আমার মূল পোস্টে যুক্ত হয়েছে।
জে

আমি জানি এটি একটি খুব পুরানো থ্রেড, তবে এখানে "সংঘর্ষ" শব্দটির উল্লেখ রয়েছে কারণ এটি হ্যাশ কোডগুলির সাথে সম্পর্কিত: লিঙ্ক । আপনি যখন হ্যাশম্যাপে কোনও মানকে একই কী দিয়ে অন্য মান রেখে প্রতিস্থাপন করেন, তখন এটি সংঘর্ষ হিসাবে বলা হয় না
তাহির আখতার

@ তাহির হুবহু সম্ভবত আমার পোস্টটি খারাপভাবে উচ্চারিত হয়েছিল। স্পষ্টির জন্য ধন্যবাদ।
জয়

7

আমার প্রথম ধারণাটি হ'ল আপনি আপনার হ্যাশম্যাপটি যথাযথভাবে শুরু করছেন তা নিশ্চিত করা। থেকে HashMap জন্য JavaDocs :

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

সুতরাং আপনি যদি খুব ছোট একটি হ্যাশম্যাপ দিয়ে শুরু করে থাকেন, তবে প্রতিবার এটির আকার পরিবর্তন করার সময় সমস্ত হ্যাশগুলি পুনরায় সংশোধন করা হবে ... আপনি যখন 2-3 মিলিয়ন সন্নিবেশ পয়েন্টে পৌঁছবেন তখন আপনি যা অনুভব করছেন তা হতে পারে।


আমি মনে করি না যে তারা কখনও সংশোধিত হয়েছে। টেবিলের আকার বৃদ্ধি করা হয়, হ্যাশগুলি রাখা হয়।
হেনিং

হ্যাশম্যাপ কিছুটা বুদ্ধিমান এবং প্রতিটি প্রবেশের জন্য করে: newIndex = storeHash & newLength;
হেনিং

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

জে, হ্যাঁ - সত্যই খারাপ শব্দ এবং আপনি যা বলেছিলেন। :)
ডেল্ফুয়েগো

1
@ ডেল্ফিয়েগো এবং @ ন্যাশ ০: ইয়েপ, উপাদানগুলির সংখ্যার সমান প্রাথমিক ক্ষমতা নির্ধারণ করা কার্যকারিতা হ্রাস করে কারণ আপনার প্রচুর সংখ্যক মিলিয়ন সংঘর্ষ হচ্ছে এবং এইভাবে আপনি কেবল সেই সামান্য পরিমাণ ব্যবহার করছেন। এমনকি যদি আপনি সমস্ত উপলভ্য এন্ট্রি ব্যবহার করেন, একই ক্ষমতা সেট করা এটি সবচেয়ে খারাপ করে দেবে !, কারণ লোড ফ্যাক্টরের কারণে আরও স্থানের জন্য অনুরোধ করা হবে। আপনাকে ব্যবহার করতে হবে initialcapactity = maxentries/loadcapacity(যেমন 30 এম, ২.২ এম এন্ট্রিগুলির জন্য 0.95) তবে এটি আপনার ক্ষেত্রে নয় , যেহেতু আপনি কেবলমাত্র 20k বা তারও কম ব্যবহার করছেন all
অস্কাররাইজ

7

আমি একটি ত্রিপক্ষীয় পদ্ধতির পরামর্শ দেব:

  1. আরও স্মৃতি সহ জাভা চালান: java -Xmx256Mউদাহরণস্বরূপ 256 মেগাবাইট সহ চালানো। প্রয়োজনে আরও ব্যবহার করুন এবং আপনার প্রচুর র‍্যাম রয়েছে।

  2. অন্য পোস্টার দ্বারা প্রস্তাবিত হিসাবে আপনার গণনা করা হ্যাশ মানগুলি ক্যাশে করুন, সুতরাং প্রতিটি বস্তু কেবল একবার তার হ্যাশ মান গণনা করে।

  3. একটি ভাল হ্যাশিং অ্যালগরিদম ব্যবহার করুন। আপনি যে পোস্ট করেছেন সে একই হ্যাশটি ফিরে আসবে যেখানে a = {0, 1} যেখানে a = {1, 0}, সমস্ত কিছুই সমান।

জাভা আপনাকে যা বিনামূল্যে দেয় তা কাজে লাগান।

public int hashCode() {
    return 31 * Arrays.hashCode(a) + Arrays.hashCode(b);
}

আমি নিশ্চিত যে এটি আপনার বিদ্যমান হ্যাশকোড পদ্ধতির চেয়ে সংঘর্ষের খুব কম সম্ভাবনা রয়েছে, যদিও এটি আপনার ডেটার সঠিক প্রকৃতির উপর নির্ভর করে।


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

7

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

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

Http://pastebin.com/f20af40b9 তে জাভা পেস্টবিন উদাহরণটি অস্কারের প্রস্তাবের উপরোক্ত সঠিকভাবে সংক্ষিপ্ত আকারে ইঙ্গিত দেয় বলে মনে হচ্ছে।

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

পেস্টবিন.com/f20af40b9 উদাহরণ (যা অস্কার কমপক্ষে দু'বার বোঝায়) অনুসরণ করে তবে প্রিন্টলাইনগুলির পরিবর্তে JUnit উক্তির ব্যবহারের জন্য সামান্য পরিবর্তিত। এই উদাহরণটি সেই প্রস্তাবটিকে সমর্থন করতে ব্যবহৃত হয় যে একই হ্যাশকোড সংঘর্ষের কারণ হয় এবং যখন ক্লাসগুলি একই হয় তখন কেবল একটি প্রবেশিকা তৈরি করা হয় (যেমন, এই নির্দিষ্ট ক্ষেত্রে কেবল একটি স্ট্রিং):

@Test
public void shouldOverwriteWhenEqualAndHashcodeSame() {
    String s = new String("ese");
    String ese = new String("ese");
    // same hash right?
    assertEquals(s.hashCode(), ese.hashCode());
    // same class
    assertEquals(s.getClass(), ese.getClass());
    // AND equal
    assertTrue(s.equals(ese));

    Map map = new HashMap();
    map.put(s, 1);
    map.put(ese, 2);
    SomeClass some = new SomeClass();
    // still  same hash right?
    assertEquals(s.hashCode(), ese.hashCode());
    assertEquals(s.hashCode(), some.hashCode());

    map.put(some, 3);
    // what would we get?
    assertEquals(2, map.size());

    assertEquals(2, map.get("ese"));
    assertEquals(3, map.get(some));

    assertTrue(s.equals(ese) && s.equals("ese"));
}

class SomeClass {
    public int hashCode() {
        return 100727;
    }
}

তবে হ্যাশকোড সম্পূর্ণ গল্প নয়। পেস্টবিন উদাহরণ যা উপেক্ষা করে তা হ'ল উভয় sএবং eseসমান: এগুলি উভয়ই "ese" স্ট্রিং। সুতরাং, ঢোকাতে বা বের ব্যবহার মানচিত্র বিষয়বস্তু পেয়ে sবা eseবা "ese"কী-এর মত সব সমতুল্য কারণ হয় s.equals(ese) && s.equals("ese")

দ্বিতীয় পরীক্ষাটি প্রমাণ করে যে এটি একই ফলশ্রুতিতে ভুল হয়েছে যে একই ক্লাসে অভিন্ন হ্যাশকোডগুলি কারণ -> টেস্টে ডাকা s -> 1হয় ese -> 2যখন মূল -> মানটি ওভাররাইট করা হয় map.put(ese, 2)। দুটি পরীক্ষায় sএবং eseএখনও একই হ্যাশকোড রয়েছে (যাচাই করা হয়েছে assertEquals(s.hashCode(), ese.hashCode());) এবং তারা একই শ্রেণি। যাইহোক, sএবং eseহয় MyStringদৃষ্টান্ত এই পরীক্ষা না জাভা String: এই পরীক্ষা সমান হওয়ার জন্য প্রাসঙ্গিক শুধু পার্থক্য সাথে - দৃষ্টান্ত String s equals String eseউপরে পরীক্ষা এক, যেহেতু MyStrings s does not equal MyString eseপরীক্ষা দুই:

@Test
public void shouldInsertWhenNotEqualAndHashcodeSame() {
    MyString s = new MyString("ese");
    MyString ese = new MyString("ese");
    // same hash right?
    assertEquals(s.hashCode(), ese.hashCode());
    // same class
    assertEquals(s.getClass(), ese.getClass());
    // BUT not equal
    assertFalse(s.equals(ese));

    Map map = new HashMap();
    map.put(s, 1);
    map.put(ese, 2);
    SomeClass some = new SomeClass();
    // still  same hash right?
    assertEquals(s.hashCode(), ese.hashCode());
    assertEquals(s.hashCode(), some.hashCode());

    map.put(some, 3);
    // what would we get?
    assertEquals(3, map.size());

    assertEquals(1, map.get(s));
    assertEquals(2, map.get(ese));
    assertEquals(3, map.get(some));
}

/**
 * NOTE: equals is not overridden so the default implementation is used
 * which means objects are only equal if they're the same instance, whereas
 * the actual Java String class compares the value of its contents.
 */
class MyString {
    String i;

    MyString(String i) {
        this.i = i;
    }

    @Override
    public int hashCode() {
        return 100727;
    }
}

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

"আসলেই নয়। হ্যাশটি একই হলে তালিকাটি তৈরি করা হয় তবে কীটি আলাদা instance উদাহরণস্বরূপ যদি কোনও স্ট্রিং হ্যাশকোড 2345 দেয় এবং পূর্ণসংখ্যা একই হ্যাশকোডকে 2345 দেয় তবে স্ট্রিংয়ের কারণে পূর্ণসংখ্যা তালিকায় প্রবেশ করা হয়। সমান (পূর্ণসংখ্যা) মিথ্যা। কিন্তু যদি আপনি একই ক্লাসে আছে (বা অন্তত .equals আয় সত্য কোণে) তারপর একই এন্ট্রি ব্যবহার করা হয়। উদাহরণস্বরূপ নতুন স্ট্রিং ( "এক") এবং `নতুন স্ট্রিং (" এক ") হিসেবে ব্যবহার করা জন্য কীগুলি, একই প্রবেশিকাটি ব্যবহার করবে ually বাস্তবে এটি হ্যাশম্যাপের পুরো পয়েন্টটি প্রথম স্থানে! নিজের জন্য দেখুন: পেস্টবিন.com/f20af40b9 - অস্কার রেইস "

পূর্ববর্তী মন্তব্যগুলির বিরুদ্ধে বনাম যা সমতুল্য কোনও উল্লেখ ছাড়াই অভিন্ন শ্রেণি এবং একই হ্যাশকোডের গুরুত্বকে সুস্পষ্টভাবে সম্বোধন করে:

"@ ডেল্ভেয়েগো: নিজের জন্য দেখুন: পেস্টবিন.com/f20af40b9 সুতরাং, এই প্রশ্নে একই শ্রেণিটি ব্যবহার করা হচ্ছে (এক মিনিট অপেক্ষা করুন, একই শ্রেণিটি সঠিকভাবে ব্যবহৃত হচ্ছে?) যা বোঝায় যে একই হ্যাশ একই প্রবেশিকা ব্যবহার করা হলে? ব্যবহৃত হয় এবং প্রবেশের "তালিকা" নেই not অস্কার রেইস "

অথবা

"আসলে এটি পারফরম্যান্সকে বাড়িয়ে দেবে। হ্যাশটেবল এক-এ আরও বেশি সংঘর্ষ যেমন কম এন্ট্রি করাতে হবে। হ্যাশ (যা ভাল দেখায়) বা হ্যাশ টেবিল (যা দুর্দান্ত কাজ করে না) আমি বাজি ধরে নিই এটি অবজেক্টে রয়েছে সৃষ্টি যেখানে কর্মক্ষমতা হ্রাস পাচ্ছে - অস্কার রেইস "

অথবা

"@ কেডিগ্রিগরি: হ্যাঁ, তবে কেবল একই ক্লাসের জন্য (যা ক্ষেত্রে) বিভিন্ন শ্রেণীর সাথে সংঘর্ষ ঘটে তবে একই প্রবেশিকা ব্যবহার করা হয়। অস্কার রেইস"

আবার অস্কার আসলে কী বলতে চাইছিল তা আমি ভুল বুঝতে পারি। তবে, তার আসল মন্তব্যগুলি যথেষ্ট বিভ্রান্তির কারণ করেছে যে কিছু স্পষ্ট পরীক্ষা দিয়ে সবকিছু পরিষ্কার করা বুদ্ধিমান বলে মনে হচ্ছে যাতে কোনও স্থির সন্দেহ নেই।


[1] - কার্যকর জাভা থেকে , জোশুয়া ব্লচের দ্বিতীয় সংস্করণ :

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

  • যদি দুটি বস্তু সমান s (ওবজ ect) পদ্ধতি অনুসারে সমান হয়, তবে দুটি বস্তুর প্রত্যেকটিতে হ্যাশকোড পদ্ধতিতে কল করার জন্য একই পূর্ণসংখ্যার ফলাফল উত্পন্ন করতে হবে।

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


5

যদি আপনার পোস্ট করা হ্যাশকোডের অ্যারেগুলি বাইট হয়, তবে সম্ভবত আপনার প্রচুর নকল হবে।

a [0] + a [1] সর্বদা 0 এবং 512 এর মধ্যে থাকবে the প্রতিটি বাইট সম্ভাব্য মান মধ্যে। যদি আপনার ডেটাটি নিয়মিত হয় তবে আপনার সম্ভবত এই পদ্ধতির কম অনন্য ফলাফল রয়েছে out


4

হ্যাশম্যাপের প্রাথমিক ক্ষমতা রয়েছে এবং হ্যাশম্যাপের কার্যকারিতা খুব হ্যাশকোডের উপর নির্ভর করে যা অন্তর্নিহিত বস্তুগুলি উত্পাদন করে।

দু'জনকেই টুইট করার চেষ্টা করুন।


4

কীগুলির যদি সেগুলির কোনও বিন্যাস থাকে তবে আপনি মানচিত্রটিকে ছোট মানচিত্রে বিভক্ত করতে পারেন এবং একটি সূচী মানচিত্র রাখতে পারেন।

উদাহরণস্বরূপ: কীগুলি: 1,2,3, .... এন 28 টি 1 মিলিয়ন এর মানচিত্র। সূচকের মানচিত্র: 1-1,000,000 -> মানচিত্র 1,000,000-2,000,000 -> মানচিত্র 2

সুতরাং আপনি দুটি অনুসন্ধান করছেন তবে মূল সেটটি হবে 1,000,000 বনাম 28,000,000। আপনি সহজেই স্টিং নিদর্শনগুলির সাথে এটি করতে পারেন।

কীগুলি যদি সম্পূর্ণ এলোমেলো হয় তবে এটি কাজ করবে না not


1
কীগুলি এলোমেলো হলেও, আপনি কী (মানক) সংরক্ষণ করতে কোন মানচিত্র নির্বাচন করতে (key.hashCode ()% 28) ব্যবহার করতে পারেন।
জুহা সিরিজালি

4

আপনি যে দুটি বাইট অ্যারে উল্লেখ করেছেন তা হ'ল আপনার সম্পূর্ণ কী, মানগুলি 0-51 সীমার মধ্যে, অনন্য এবং a এবং b অ্যারেগুলির মধ্যে ক্রমটি নগণ্য হয়, আমার গণিত আমাকে বলে যে কেবলমাত্র প্রায় 26 মিলিয়ন সম্ভাব্য অনুমান এবং আপনি সম্ভবত সমস্ত সম্ভাব্য কীগুলির মান সহ মানচিত্রটি পূরণ করার চেষ্টা করছেন।

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


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

4

আমি এখানে দেরি করেছি, তবে বড় মানচিত্র সম্পর্কে দু'জন মন্তব্য করেছেন:

  1. অন্যান্য পোস্টে দৈর্ঘ্যে আলোচিত হিসাবে, একটি ভাল হ্যাশকোড () সহ, একটি মানচিত্রে 26 এম এন্ট্রি কোনও বড় বিষয় নয়।
  2. তবে, এখানে একটি সম্ভাব্য লুকানো ইস্যুটি দৈত্য মানচিত্রের জিসি প্রভাব impact

আমি একটি অনুমান করছি যে এই মানচিত্রগুলি দীর্ঘকালীন। যেমন আপনি এগুলিকে বসান এবং তারা অ্যাপ্লিকেশনটির সময়কাল ধরে থাকে। আমিও ধরে নিচ্ছি যে অ্যাপটি নিজেই দীর্ঘকালীন - কোনওরকম সার্ভারের মতো।

একটি জাভা হ্যাশম্যাপে প্রতিটি প্রবেশের জন্য তিনটি অবজেক্টের প্রয়োজন: কী, মান এবং এন্ট্রি যা তাদের একসাথে যুক্ত করে। সুতরাং মানচিত্রে 26 এম এন্ট্রির অর্থ 26 এম * 3 == 78 এম অবজেক্ট। আপনি পুরো জিসিকে আঘাত না করা পর্যন্ত এটি ঠিক আছে। তাহলে আপনি একটি বিরতি-দুনিয়া সমস্যা পেয়েছেন problem জিসি 78 এম এর প্রতিটি বস্তুর দিকে নজর দেবে এবং নির্ধারণ করবে যে তারা সমস্ত জীবিত। 78 এম + অবজেক্টগুলি দেখতে অনেকগুলি অবজেক্ট। যদি আপনার অ্যাপটি মাঝে মাঝে দীর্ঘ (সম্ভবত বেশ কয়েক সেকেন্ড) বিরতি সহ্য করতে পারে তবে সমস্যা নেই। যদি আপনি কোনও বিলম্বতার গ্যারান্টি অর্জনের চেষ্টা করছেন তবে আপনার একটি বড় সমস্যা হতে পারে (অবশ্যই যদি আপনি বিলম্বের গ্যারান্টি চান তবে জাভা বেছে নেওয়ার প্ল্যাটফর্ম নয় :)) যদি আপনার মানচিত্রে মানগুলি দ্রুত মন্থন করে তবে আপনি ঘন ঘন পূর্ণ সংগ্রহের সাথে শেষ করতে পারেন যা সমস্যাটি ব্যাপকভাবে মিশ্রিত করে।

আমি এই সমস্যাটির দুর্দান্ত সমাধান সম্পর্কে জানি না। ধারনা:

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

জাভাতে দৈত্য মানচিত্রের সাথে প্রচুর সময় ব্যয় করেছেন এমন ব্যক্তির কাছ থেকে কেবল কিছু চিন্তাভাবনা।



3

আমার ক্ষেত্রে আমি 26 মিলিয়ন এন্ট্রি সহ একটি মানচিত্র তৈরি করতে চাই। স্ট্যান্ডার্ড জাভা হ্যাশম্যাপ ব্যবহার করে পুট রেট 2-3 মিলিয়ন সন্নিবেশের পরে অসহনীয়ভাবে ধীর হয়ে যায়।

আমার পরীক্ষা থেকে (২০০৯ সালে ছাত্র প্রকল্প):

  • আমি 1 থেকে 100.000 নং 100.000 নোডের জন্য একটি লাল কালো গাছ তৈরি করেছি। এটি 785.68 সেকেন্ড (13 মিনিট) নিয়েছিল। এবং আমি 1 মিলিয়ন নোডের জন্য আরবিট্রি তৈরি করতে ব্যর্থ হয়েছি (হ্যাশম্যাপের সাথে আপনার ফলাফলের মতো)।
  • "প্রাইম ট্রি" ব্যবহার করে, আমার অ্যালগোরিদম ডেটা স্ট্রাকচার। আমি 21 মিলিয়ন নোডের জন্য 21.29 সেকেন্ডের মধ্যে একটি বৃক্ষ / মানচিত্র তৈরি করতে পারি (র‌্যাম: 1.97 জিবি)। কী-মূল্যের মূল্য হ'ল ও (1)।

দ্রষ্টব্য: "প্রাইম ট্রি" 1 থেকে 10 মিলিয়ন থেকে "অবিচ্ছিন্ন কীগুলিতে" সেরা কাজ করে। হাশম্যাপের মতো কীগুলি নিয়ে কাজ করার জন্য আমাদের কিছু নাবালিকাকে সামঞ্জস্য করতে হবে।


তো, # প্রাইমট্রি কী? সংক্ষেপে, এটি বাইনারি গাছের মতো একটি গাছের ডেটা কাঠামো, শাখাগুলি সংখ্যাগুলি প্রধান সংখ্যা ("2" -বাইনারি পরিবর্তে) are


আপনি কি কিছু লিঙ্ক বা বাস্তবায়ন ভাগ করতে পারেন?
বেনজ



1

আপনি এটি করতে এম্বেড থাকা ডাটাবেস ব্যবহার করার বিষয়টি বিবেচনা করেছেন? এ বার্কলে ডিবি । এটি ওপেন সোর্স, এখন ওরাকেলের মালিকানাধীন।

এটি কী-> মান জুটি হিসাবে সমস্ত কিছু সঞ্চয় করে, এটি কোনও আরডিবিএমএস নয়। এবং এটি দ্রুত হতে লক্ষ্য।


2
সিরিয়ালাইজেশন / আইও ওভারহেডের কারণে বার্কলে ডিবি এই সংখ্যার এন্ট্রিগুলির পক্ষে দ্রুত পর্যাপ্ত কোথাও নেই; এটি হ্যাশম্যাপের চেয়ে দ্রুত আর কখনও হতে পারে না এবং ওপি দৃ়তার বিষয়ে চিন্তা করে না। আপনার পরামর্শটি ভাল নয়।
অক্সবো_লাক্স 21

1

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

তারপরে আমি প্রকৃতপক্ষে কী ঘটছে এবং মৃত্যুদন্ড কার্যকর করার সময়টি কোথায় ব্যয় করা হয়েছে তা দেখতে প্রোফাইলার ব্যবহার করার পরামর্শ দেব suggest উদাহরণস্বরূপ, হ্যাশকোড () পদ্ধতিটি কয়েক বিলিয়ন বার কার্যকর হয়েছে?

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

আর একটি বিকল্প হ'ল কিছু ডাটাবেস ইঞ্জিন যা সম্পূর্ণ এসকিউএল আরডিবিএমএসের চেয়ে হালকা ওজন। বার্কলে ডিবির মতো কিছু , হতে পারে।

দ্রষ্টব্য, আমার কাছে এই পণ্যগুলির পারফরম্যান্সের ব্যক্তিগতভাবে কোনও অভিজ্ঞতা নেই তবে তারা চেষ্টা করার মতো হতে পারে।


1

আপনি কী অবজেক্টে গণিত হ্যাশ কোডটি ক্যাশে দেওয়ার চেষ্টা করতে পারেন।

এটার মতো কিছু:

public int hashCode() {
  if(this.hashCode == null) {
     this.hashCode = computeHashCode();
  }
  return this.hashCode;
}

private int computeHashCode() {
   int hash = 503;
   hash = hash * 5381 + (a[0] + a[1]);
   hash = hash * 5381 + (b[0] + b[1] + b[2]);
   return hash;
}

হ্যাশকোড প্রথমবার গণনা করার পরে অবশ্যই কীগুলির বিষয়বস্তু পরিবর্তন না করার বিষয়ে আপনাকে অবশ্যই সতর্ক থাকতে হবে।

সম্পাদনা: দেখে মনে হচ্ছে ক্যাশিংয়ের কোড মানগুলি সার্থক হয় না যখন আপনি প্রতিটি মান একবারে একবারে যুক্ত করেন। অন্য কোনও পরিস্থিতিতে এটি কার্যকর হতে পারে।


নীচের দিকে ইশারা করা হয়েছে যে, হ্যাশম্যাপে যখন এটির আকার পরিবর্তন করা হবে তখন হ্যাশকোডের অবজেক্টগুলির কোনও পুনর্নির্মাণ নেই, যাতে এটি আপনার কোনও লাভ করে না।
delduego

1

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

আপনার যদি সর্বদা 0..51 ব্যাপ্তির মান থাকে তবে এই মানগুলির প্রত্যেকটির প্রতিনিধিত্ব করতে 6 বিট লাগবে। আপনার যদি সর্বদা 5 টি মান থাকে তবে আপনি বাম-শিফট এবং সংযোজন সহ 30-বিট হ্যাশকোড তৈরি করতে পারেন:

    int code = a[0];
    code = (code << 6) + a[1];
    code = (code << 6) + b[0];
    code = (code << 6) + b[1];
    code = (code << 6) + b[2];
    return code;

বাম-শিফটটি দ্রুত, তবে আপনাকে হ্যাশকোডগুলি ছেড়ে দেবে যা সমানভাবে বিতরণ করা হয়নি (কারণ 6 বিটগুলি 0,63 এর পরিসীমা বোঝায়)। একটি বিকল্প হ্যাশকে 51 দিয়ে গুণ এবং প্রতিটি মান যুক্ত করা হয়। এটি এখনও পুরোপুরি বিতরণ করা হবে না (উদাঃ, {2,0} এবং {1,52 coll সংঘর্ষে যাবে), এবং শিফ্টের চেয়ে ধীর হবে।

    int code = a[0];
    code *= 51 + a[1];
    code *= 51 + b[0];
    code *= 51 + b[1];
    code *= 51 + b[2];
    return code;

@ কেডিগ্রিগরি: আমি অন্য কোথাও "আরও সংঘর্ষকে আরও কাজ বোঝায়" সম্পর্কে উত্তর দিয়েছি :)
অস্কার রাইজ

1

নির্দেশিত হিসাবে, আপনার হ্যাশকোড বাস্তবায়নে অনেকগুলি সংঘর্ষ রয়েছে এবং এটি ঠিক করার ফলে শালীন কার্যকারিতা দেখা উচিত। তদুপরি, হ্যাশকোডগুলি ক্যাচ করা এবং দক্ষতার সাথে সমান প্রয়োগ করা সহায়তা করবে।

আপনার আরও আরও অনুকূলিতকরণ প্রয়োজন হলে:

আপনার বিবরণ অনুসারে কেবল (52 * 51/2) * (52 * 51 * 50/6) = 29304600 বিভিন্ন কী (যার মধ্যে 26000000, অর্থাৎ প্রায় 90% উপস্থিত থাকবে)। অতএব, আপনি কোনও সংঘর্ষ ছাড়াই একটি হ্যাশ ফাংশন ডিজাইন করতে পারেন এবং আপনার ডেটা ধরে রাখতে হ্যাশম্যাপের পরিবর্তে একটি সাধারণ অ্যারে ব্যবহার করতে পারেন, মেমরির খরচ কমাতে এবং দেখার গতি বাড়িয়ে তুলতে পারেন:

T[] array = new T[Key.maxHashCode];

void put(Key k, T value) {
    array[k.hashCode()] = value;

T get(Key k) {
    return array[k.hashCode()];
}

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

ধরে নেওয়া aএবং bবাছাই করা, আপনি নিম্নলিখিত হ্যাশ ফাংশনটি ব্যবহার করতে পারেন:

public int hashCode() {
    assert a[0] < a[1]; 
    int ahash = a[1] * a[1] / 2 
              + a[0];

    assert b[0] < b[1] && b[1] < b[2];

    int bhash = b[2] * b[2] * b[2] / 6
              + b[1] * b[1] / 2
              + b[0];
    return bhash * 52 * 52 / 2 + ahash;
}

static final int maxHashCode = 52 * 52 / 2 * 52 * 52 * 52 / 6;  

আমি মনে করি এটি সংঘর্ষমুক্ত। এটি প্রমাণিত করা গণিতের দিকে ঝুঁকানো পাঠকের অনুশীলন হিসাবে ছেড়ে দেওয়া হয়েছে।


1

ইন কার্যকরী জাভা: প্রোগ্রামিং ভাষা গাইড (জাভা সিরিজ)

অধ্যায় 3 আপনি হ্যাশকোড () গণনা করার সময় অনুসরণ করতে ভাল নিয়মগুলি পেতে পারেন।

বিশেষভাবে:

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


0

শুরুতে একটি বড় মানচিত্র বরাদ্দ করুন। যদি আপনি জানেন তবে এটিতে 26 মিলিয়ন এন্ট্রি থাকবে এবং এটির জন্য আপনার স্মৃতি রয়েছে, একটি করুন new HashMap(30000000)

আপনি কি নিশ্চিত যে 26 মিলিয়ন কী এবং মান সহ 26 মিলিয়ন এন্ট্রিগুলির জন্য আপনার যথেষ্ট মেমরি রয়েছে? এটি আমার কাছে অনেক স্মৃতি মনে হচ্ছে। আপনি কি নিশ্চিত যে আবর্জনা সংগ্রহ আপনার 2 থেকে 3 মিলিয়ন চিহ্নে এখনও ঠিক আছে? আমি কল্পনা করতে পারি যে বাধা হিসাবে।


2
ওহ, অন্য জিনিস। মানচিত্রের একক পজিশনে বড় লিঙ্কযুক্ত তালিকা এড়াতে আপনার হ্যাশ কোডগুলি সমানভাবে বিতরণ করতে হবে।
নবীন

0

আপনি দুটি জিনিস চেষ্টা করতে পারেন:

  • আপনার hashCodeপদ্ধতিটিকে কিছু সহজ এবং আরও কার্যকর যেমন একটানা ইনট হিসাবে ফিরিয়ে আনুন

  • আপনার মানচিত্রটি এইভাবে শুরু করুন:

    Map map = new HashMap( 30000000, .95f );

এই দুটি ক্রিয়াকলাপটি কাঠামোটি পুনর্নির্মাণের পরিমাণটি হ্রাস করবে এবং আমি মনে করি এটি পরীক্ষা করা বেশ সহজ।

যদি এটি কাজ না করে তবে একটি আলাদা স্টোরেজ যেমন একটি আরডিবিএমএস ব্যবহার করে বিবেচনা করুন।

সম্পাদনা

আশ্চর্যজনক যে প্রাথমিক ক্ষমতা সেট করা আপনার ক্ষেত্রে কর্মক্ষমতা হ্রাস করে।

জাভাডোকগুলি থেকে দেখুন :

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

আমি একটি মাইক্রোবিচমার্ক তৈরি করেছি (যা কোনও ব্যক্তির দ্বারা নির্দিষ্ট নয় তবে অন্তত এই বিষয়টি প্রমাণ করে)

$cat Huge*java
import java.util.*;
public class Huge {
    public static void main( String [] args ) {
        Map map = new HashMap( 30000000 , 0.95f );
        for( int i = 0 ; i < 26000000 ; i ++ ) { 
            map.put( i, i );
        }
    }
}
import java.util.*;
public class Huge2 {
    public static void main( String [] args ) {
        Map map = new HashMap();
        for( int i = 0 ; i < 26000000 ; i ++ ) { 
            map.put( i, i );
        }
    }
}
$time java -Xms2g -Xmx2g Huge

real    0m16.207s
user    0m14.761s
sys 0m1.377s
$time java -Xms2g -Xmx2g Huge2

real    0m21.781s
user    0m20.045s
sys 0m1.656s
$

সুতরাং, পুনঃস্থাপনের কারণে প্রাথমিক সামর্থ্যটি 21 থেকে 16 এ নেমে আসে। এটি hashCode"সুযোগের ক্ষেত্র" হিসাবে আপনার পদ্ধতিটি ছেড়ে দেয় ;)

সম্পাদনা

হ্যাশম্যাপ নয়

আপনার শেষ সংস্করণ অনুযায়ী।

আমি মনে করি আপনার অ্যাপ্লিকেশনটি সত্যই প্রোফাইল করা উচিত এবং এটি কোথায় মেমরি / সিপিইউ গ্রাস করছে তা দেখতে হবে।

আপনার একই বাস্তবায়ন করার জন্য আমি একটি শ্রেণি তৈরি করেছি hashCode

এই হ্যাশ কোডটি লক্ষ লক্ষ সংঘর্ষ দেয়, তারপরে হ্যাশম্যাপে এন্ট্রি নাটকীয়ভাবে হ্রাস পায়।

আমি আমার পূর্বের পরীক্ষায় 21, 16 থেকে 10 ও 8 এর দশকে পাস করেছি। কারণ হ্যাশকোড সংখ্যক সংখ্যক সংঘর্ষকে উস্কে দেয় এবং আপনি যে 26 এম অবজেক্ট মনে করেন তা আপনি সংরক্ষণ করছেন না তবে একটি উল্লেখযোগ্য নিম্ন সংখ্যা (প্রায় 20k আমি বলব) তাই:

সমস্যাগুলি হ্যাশম্যাপ নয় আপনার কোডের অন্য কোথাও।

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

আপনার ক্লাস আমার বাস্তবায়ন এখানে।

নোট আপনি আমার মান হিসাবে 1212 থেকে 127 না করে 0-01 রেঞ্জ ব্যবহার করিনি এবং পুনরাবৃত্তি স্বীকার করেছেন, কারণ আপনি আপনার প্রশ্ন আপডেট করার আগে আমি এই পরীক্ষাটি করেছি

পার্থক্যটি হ'ল আপনার শ্রেণিতে আরও সংঘর্ষ হবে যাতে মানচিত্রে কম আইটেম সঞ্চিত থাকে।

import java.util.*;
public class Item {

    private static byte w = Byte.MIN_VALUE;
    private static byte x = Byte.MIN_VALUE;
    private static byte y = Byte.MIN_VALUE;
    private static byte z = Byte.MIN_VALUE;

    // Just to avoid typing :) 
    private static final byte M = Byte.MAX_VALUE;
    private static final byte m = Byte.MIN_VALUE;


    private byte [] a = new byte[2];
    private byte [] b = new byte[3];

    public Item () {
        // make a different value for the bytes
        increment();
        a[0] = z;        a[1] = y;    
        b[0] = x;        b[1] = w;   b[2] = z;
    }

    private static void increment() {
        z++;
        if( z == M ) {
            z = m;
            y++;
        }
        if( y == M ) {
            y = m;
            x++;
        }
        if( x == M ) {
            x = m;
            w++;
        }
    }
    public String toString() {
        return "" + this.hashCode();
    }



    public int hashCode() {
        int hash = 503;
        hash = hash * 5381 + (a[0] + a[1]);
        hash = hash * 5381 + (b[0] + b[1] + b[2]);
        return hash;
    }
    // I don't realy care about this right now. 
    public boolean equals( Object other ) {
        return this.hashCode() == other.hashCode();
    }

    // print how many collisions do we have in 26M items.
    public static void main( String [] args ) {
        Set set = new HashSet();
        int collisions = 0;
        for ( int i = 0 ; i < 26000000 ; i++ ) {
            if( ! set.add( new Item() ) ) {
                collisions++;
            }
        }
        System.out.println( collisions );
    }
}

এই ক্লাসটি ব্যবহার করে পূর্ববর্তী প্রোগ্রামের কী রয়েছে

 map.put( new Item() , i );

আমাকে দেয়:

real     0m11.188s
user     0m10.784s
sys 0m0.261s


real     0m9.348s
user     0m9.071s
sys  0m0.161s

3
অস্কার, উপরের দিকে অন্য যেভাবে নির্দেশিত হয়েছে (আপনার মন্তব্যের প্রতিক্রিয়া হিসাবে), আপনি মনে করছেন যে আরও সংঘর্ষগুলি ভাল is এটা খুব ভাল না। একটি সংঘর্ষের অর্থ একটি প্রদত্ত হ্যাশের স্লটটিতে একটি প্রবেশিকা রয়েছে যা এন্ট্রিগুলির একটি তালিকা রয়েছে এবং এই স্লটটি অ্যাক্সেস করার পরে এই তালিকাটি অনুসন্ধান / ট্র্যাভারে যেতে হবে।
delfuego

@ ডেলফুয়েগো: সত্যই নয়, এটি তখনই ঘটে যখন আপনি বিভিন্ন ক্লাস ব্যবহার করে সংঘর্ষের মুখোমুখি হন তবে একই শ্রেণীর জন্য একই প্রবেশিকা ব্যবহার করা হয়;)
অস্কাররিজ

2
@ অস্কার - এমএকের উত্তর দিয়ে আমার প্রতি আপনার প্রতিক্রিয়া দেখুন। হ্যাশম্যাপ প্রতিটি হ্যাশ বালতিতে এন্ট্রিগুলির একটি লিঙ্কযুক্ত তালিকা বজায় রাখে এবং সেই তালিকাটিতে প্রতিটি উপাদানগুলিতে কলিংয়ের সমান হয় () ks এর সাথে বস্তুর শ্রেণীর কোনও যোগসূত্র নেই (সমান () এর উপর একটি শর্ট সার্কিট ব্যতীত)।
কেডিগ্রিগরি

1
@ অস্কার - আপনার উত্তরটি পড়ে মনে হচ্ছে আপনি যদি ধরে নিচ্ছেন যে হ্যাশকোডগুলি একই হয় তবে আপনি সমান () সমান হয়ে উঠবেন। এটি সমান / হ্যাশকোড চুক্তির অংশ নয়। আমি যদি ভুল বুঝে থাকি তবে এই মন্তব্যটি উপেক্ষা করুন।
কেডিগ্রিগরি

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


0

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


0

ব্যবহৃত জনপ্রিয় হ্যাশিং পদ্ধতিগুলি বড় সেটগুলির জন্য খুব ভাল নয় এবং উপরে উল্লিখিত হিসাবে ব্যবহৃত হ্যাশটি বিশেষত খারাপ। উচ্চ মিশ্রণ এবং কভারেজ যেমন হ্যাশ অ্যালগরিদম যেমন বুজহ্যাশ ব্যবহার করা ভাল ( http://www.java2s.com/ কোড / জাভা / ডেভেলপমেন্ট-ক্লাস / অভারিজেটিজভাহালসালগোরিদিম্বেসডেন্ট বুজহ্যাশালগোরিটম.htm এ নমুনা প্রয়োগ )

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