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


9

আমি সম্প্রতি একটি বড় সংস্থায় কাজ করার সময় আমি লক্ষ্য করেছি যে সেখানকার প্রোগ্রামাররা এই কোডিং স্টাইলটি অনুসরণ করেছে:

ধরুন আমার একটি ফাংশন রয়েছে যা ইনপুটটি A হলে 12, ইনপুটটি B হলে 21 এবং ইনপুট সি হলে 45 দেয় returns

সুতরাং আমি এই হিসাবে ফাংশন স্বাক্ষর লিখতে পারেন:

int foo(String s){
    if(s.equals("A"))      return 12;
    else if(s.equals("B")) return 21;
    else if(s.equals("C")) return 45;
    else throw new RuntimeException("Invalid input to function foo");
}

তবে কোড পর্যালোচনায় আমাকে ফাংশনটি নিম্নলিখিতটিতে পরিবর্তন করতে বলা হয়েছিল:

int foo(String s){
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("A", 12);
    map.put("B", 21);
    map.put("C", 45);
    return map.get(s);
}

দ্বিতীয় কোডটি কেন প্রথমটির চেয়ে ভাল is আমি নিজেকে বোঝাতে পারি না। দ্বিতীয় কোডটি অবশ্যই চালাতে আরও বেশি সময় নেবে।

দ্বিতীয় কোডটি ব্যবহারের একমাত্র কারণ হ'ল এটি আরও ভাল পাঠযোগ্যতার প্রস্তাব দেয়। কিন্তু যদি ফাংশনটি অনেকবার কল করা হয় তবে দ্বিতীয় ফাংশনটি ইউটিলিটির কলিংটির চলমান সময়কে কমিয়ে দেবে না?

আপনি এ ব্যপারে কী ভাবছেন?


4
তিনটি মানের জন্য একটি মানচিত্র ওভারকিলের switchচেয়ে মনে হয় (এর চেয়ে বেশি উপযুক্ত বলে মনে হয় if-else)। তবে এক পর্যায়ে এটি সমস্যাযুক্ত হয়ে ওঠে। মানচিত্রটি ব্যবহারের প্রধান সুবিধা হ'ল আপনি এটিকে ফাইল বা টেবিল ইত্যাদি থেকে লোড করতে পারেন যদি আপনি মানচিত্রে ইনপুটটিকে কঠোরভাবে কোডিং করছেন তবে আমি একটি স্যুইচ দিয়ে খুব বেশি মূল্য দেখছি না।
জিমি জেমস

উত্তর:


16

বিষয়টি হ'ল হ্যাশম্যাপের ক্রিয়াকলাপের বাইরে নিয়ে যাওয়া এবং এটি একবার করা (বা অন্যথায় তুলনায় কম সময়ে) to

private static final Map<String, Integer> map;
static{
    Map<String, Integer> temp = new HashMap<String, Integer>();
    temp.put("A", 12);
    temp.put("B", 21);
    temp.put("C", 45);
    map = Collections.unmodifiableMap(temp);//make immutable
}

int foo(String s){
    if(!map.containsKey(s))
        throw new RuntimeException("Invalid input to function foo");

    return map.get(s);
}

যাইহোক জাভা 7 সাল থেকে সুইচগুলিতে (চূড়ান্ত) স্ট্রিং রাখতে সক্ষম হয়েছে:

int foo(String s){
    switch(s){
    case "A":
        return 12;
    case "B": 
        return 21;
    case "C": 
        return 45;
    default: throw new RuntimeException("Invalid input to function foo");
}

1
আমি দেখতে পাচ্ছি না কীভাবে এটি ওপিএস প্রশ্নের উত্তর দেয়, সুতরাং -1। সুইচ প্রস্তাব দেওয়ার জন্য +1 করুন
user949300

এটি দেখায় যে কীভাবে কোডিং শৈলীটি যথাযথভাবে বাস্তবায়িত করা যায় এবং প্রকৃত অর্থে বোধগম্যতা তৈরি করতে এবং সম্ভবত কার্য সম্পাদনাকে উন্নত করতে পারে। এটি 3 টি পছন্দের জন্য এখনও বোঝায় না তবে মূল কোডটি সম্ভবত অনেক দীর্ঘ ছিল probably
ফ্লোরিয়ান এফ

12

আপনার দ্বিতীয় উদাহরণে Mapঅপ্রয়োজনীয় সূচনা ওভারহেড এড়াতে প্রাইভেট স্ট্যাটিক সদস্য হওয়া উচিত।

বৃহত পরিমাণের মানগুলির জন্য, মানচিত্রটি আরও ভাল সম্পাদন করবে। হ্যাশ টেবিল ব্যবহার করে, ধ্রুব সময়ে উত্তর সন্ধান করতে পারে। একাধিক-যদি নির্মাণটি সঠিক উত্তর না পাওয়া পর্যন্ত প্রতিটি সম্ভাবনার সাথে ইনপুট তুলনা করতে হয়।

অন্য কথায়, মানচিত্রের অনুসন্ধানটি হ'ল (1) যেখানে ifগুলি হ'ল (এন) যেখানে এন সম্ভাব্য ইনপুটগুলির সংখ্যা।

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

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


হ্যাঁ, প্রচুর পরিমাণে মানগুলির জন্য, মানচিত্রটি আরও ভাল সম্পাদন করবে। তবে মানগুলির পরিমাণ নির্ধারিত এবং এটি তিনটি।
রেমকো গ্রিলিচ

মানচিত্রটি তৈরি করা হ'ল হে (এন) কেবল এটির অনুসন্ধান ও (1)।
পিটার বি

ভালো কথা, আমি আমার উত্তরটি পরিষ্কার করে দিয়েছি।

মানচিত্রে অটো-আনবক্সিংও প্রয়োজন যা পারফরম্যান্সকে কিছুটা প্রভাবিত করে।
user949300

জাভাতে @ ব্যবহারকারী949300, হ্যাঁ, এবং প্রশ্নের কোডটি জাভা বলে মনে হচ্ছে। তবে এটি কোনও ভাষার সাথে ট্যাগ করা হয়নি এবং এ পদ্ধতিটি একাধিক ভাষায় কাজ করে (সি # এবং সি ++ সহ, যার মধ্যে দুটিতে বক্সিং প্রয়োজন)।

3

সফ্টওয়্যারটিতে দুটি গতি রয়েছে: কোডটি লিখতে / পড়তে / ডিবাগ করতে সময় লাগে; এবং কোডটি কার্যকর করতে সময় লাগে।

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

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


3
ভাল, যে আপত্তি পৃথক্ যখন কেউ এর পরিবর্তে একটি সুইচ সঙ্গে তুলনা করে ... পড়ে
Deduplicator

আপনি যদি এক লাইনে if-বিবৃতি লিখেন তবে আলাদা হয়ে যায়।
gnasher729

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

2

আমি হ্যাশম্যাপ স্টাইলের উত্তরটি খুব পছন্দ করি।

এর জন্য একটি মেট্রিক আছে

সাইক্লোমেটিক জটিলতা নামে একটি কোড মানের মেট্রিক রয়েছে । এই মেট্রিকটি মূলত কোডের মাধ্যমে বিভিন্ন পাথের সংখ্যা গণনা করে ( কীভাবে সাইক্লোমেটিক জটিলতা গণনা করবেন )।

প্রতিটি সম্ভাব্য সম্পাদনের পথের জন্য একটি পদ্ধতি দু'টি বোঝার জন্য আরও শক্ত এবং শক্ত হয়ে ওঠে এবং যথার্থতার জন্য সম্পূর্ণ পরীক্ষা করে।

এটি "কীওয়ার্ডগুলি নিয়ন্ত্রণ করে" যেমন: আইএফএস, এলেস, থিসস, ইত্যাদি ... লিভারেজের বুলিয়ান পরীক্ষা যে ভুল হতে পারে তা এটিকে উত্সাহিত করে। "নিয়ন্ত্রণকারী কীওয়ার্ডগুলি" এর বারবার ব্যবহার ভঙ্গুর কোড তৈরি করে।

অতিরিক্ত বেনিফিট

এছাড়াও, "মানচিত্র ভিত্তিক পদ্ধতির" বিকাশকারীদের ইনপুট-আউটপুট জুটিকে একটি ডেটাসেট হিসাবে ভাবতে উত্সাহিত করে যা এক্সট্রাক্ট, পুনরায় ব্যবহার, রানটাইম সময়ে ম্যানিপুলেট, পরীক্ষিত এবং যাচাই করা যেতে পারে। উদাহরণস্বরূপ, নীচে আমি "foo" আবার লিখেছি যাতে আমরা স্থায়ীভাবে "A-> 12, B-> 21, C-> 45" এ লক না হয়ে থাকি:

int foo(String s){
    HashMap<String, Integer> map = getCurrentMapping();
    return map.get(s);
}

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


1
রানটাইম নমনীয়তা যুক্ত করা হয় হয় একটি দুর্দান্ত প্রত্যাশিত ধারণা, বা অযৌক্তিক ওভার-ইঞ্জিনিয়ারিং যা ঘটছে তা নির্ধারণ করা আরও শক্ত করে তোলে। :-)।
user949300

@ জিমি জেমস লিঙ্কটি আমার পক্ষে কাজ করে: এটি হ'ল লিপয়েন্টিপয়েন্ট
ইভান

1
@ user949300 মুল বক্তব্যটি হ'ল "foo" পদ্ধতিটিকে সমর্থনকারী কী / মান ডেটা একটি পৃথক ধারণা যা কিছুটা স্বচ্ছতার যোগ্যতা অর্জন করতে পারে । মানচিত্রটি বিচ্ছিন্ন করতে আপনি যে পরিমাণ কোড লিখতে চান তা মানচিত্রের কতগুলি আইটেম রয়েছে এবং এই আইটেমগুলিতে কতবার পরিবর্তন হতে পারে তার উপর নির্ভর করে on
ইভান

1
@ user949300 কারণটির কারণ হিসাবে আমি যদি-অন্য চেইনটি বের করার পরামর্শ দিই তা হ'ল আমি যদি দেখেছি যে অন্য গ্রুপগুলি রয়েছে কিনা exist প্রকারের মতো রোচের মতো, যদি যদি অন্য পদ্ধতিতে চেইনের উপর ভিত্তি করে একটি পদ্ধতি থাকে তবে কোড-বেসে অন্য কোনও পদ্ধতিতে অনুরূপ / অভিন্ন যদি-অন্য শৃঙ্খলা থাকতে পারে। মানচিত্রটি উত্তোলনের মাধ্যমে লভ্যাংশ প্রদান করা হয় যদি আমরা ধরে নিই যে অন্য পদ্ধতি আছে যা একই রকম চেহারা / স্যুইচ-এর মতো যুক্তি কাঠামো ব্যবহার করে।
ইভান

আমিও সদৃশ দেখেছি, প্রায় একই জায়গায় / অন্য ব্লকগুলি পুরো জায়গায় ছড়িয়ে ছিটিয়ে থাকলে। ভাল করে বলুন
জন চেস্টারফিল্ড

1

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

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

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

def foo(s):
    return {
               "A" : 12,
               "B" : 21,
               "C" : 45,
           }[s]

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


-1 প্রশ্নের উত্তর নয়।
পিটার বি

কি অর্থে? আমি লেখককে যদি অন্য কোনও চেইনকে মানচিত্রের সাথে ডেটা এবং কোড পৃথক করে রাখার ভিত্তিতে প্রতিস্থাপন করতে বলতাম। এটি সমস্ত কারণেই প্রথম কোডের চেয়ে দ্বিতীয় কোডটি আরও ভাল, যদিও সমস্ত মানচিত্র.পুট কলগুলি দুর্ভাগ্যজনক This
জন চেস্টারফিল্ড

2
@ জোনচেস্টারফিল্ড এই উত্তরটি মূলত "আরও ভাল ভাষা ব্যবহার করুন", যা খুব কমই সহায়ক।
ওয়ালেপ করুন

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

কিছু পুরানো জাভা কোডে আমার খুব অনুরূপ কিছুটির জন্য কয়েকটি মানচিত্রের প্রয়োজন ছিল, তাই 2-ডি অ্যারের এন-ডাইমেনশনাল অ্যারেগুলিকে মানচিত্রে রূপান্তর করতে একটি সামান্য ইউটিলিটি লিখেছিলেন। কিছুটা হ্যাকি তবে ভাল কাজ করেছে। এই উত্তরটি এত সহজে এবং সহজেই JSONy স্বরলিপি সমর্থন করার ক্ষেত্রে পাইথন / জেএসের শক্তি চিহ্নিত করে।
user949300
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.