java যখন জাভা এ্যার্রলিস্টের উপর লিঙ্কডলিস্ট ব্যবহার করবেন?



15 Answers

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

যেহেতু রেফারেন্সগুলি তাদের আপেক্ষিক সিস্টেমে 32 বা 64 বিট (এমনকি যখন নাল) হয়, তাই আমি 32 এবং 64 বিট LinkedLists এবং LinkedLists জন্য 4 সেটের ডেটা অন্তর্ভুক্ত করেছি।

দ্রষ্টব্য: ArrayList লাইনগুলির জন্য দেখানো মাপ ArrayList তালিকাগুলির জন্য হয় - অনুশীলনে, একটি ArrayList ব্যাকিং অ্যারের ক্ষমতাটি তার বর্তমান উপাদান গণনার তুলনায় সাধারণত বড় হয়।

দ্রষ্টব্য 2: (ধন্যবাদ BeeOnRope) কম্প্রেসযুক্ত হিসাবে এখন মধ্য জেডি 6 এবং আপ থেকে ডিফল্ট হয়, 64-বিট মেশিনগুলির জন্য নীচের মান মূলত তাদের 32-বিট সমতুল্যগুলির সাথে মিলবে, যতক্ষন না আপনি অবশ্যই এটি বন্ধ করে দেবেন।

ফলাফলটি স্পষ্টভাবে দেখায় যে LinkedList চেয়ে অনেক বেশি, বিশেষত খুব উচ্চ উপাদান গণনার সাথে। যদি মেমরি একটি ফ্যাক্টর হয়, LinkedLists স্পষ্ট LinkedLists

আমি অনুসরণ করা সূত্র, আমি কিছু ভুল করেছি যদি আমি জানতে এবং আমি এটা ঠিক করা হবে। 'বি' 32 বা 64 বিট সিস্টেমের জন্য 4 বা 8 হয়, এবং 'n' উপাদানগুলির সংখ্যা। মোডগুলির কারণটি লক্ষ্য করুন কারণ জাভাতে থাকা সমস্ত বস্তুগুলি 8 বাইট স্পেসের একাধিকটি গ্রহণ করবে কিনা তা নির্বিশেষে ব্যবহার করা হয়েছে কিনা তা বিবেচনা করে।

ArrayList :

ArrayList object header + size integer + modCount integer + array reference + (array oject header + b * n) + MOD(array oject, 8) + MOD(ArrayList object, 8) == 8 + 4 + 4 + b + (12 + b * n) + MOD(12 + b * n, 8) + MOD(8 + 4 + 4 + b + (12 + b * n) + MOD(12 + b * n, 8), 8)

LinkedList :

LinkedList object header + size integer + modCount integer + reference to header + reference to footer + (node object overhead + reference to previous element + reference to next element + reference to element) * n) + MOD(node object, 8) * n + MOD(LinkedList object, 8) == 8 + 4 + 4 + 2 * b + (8 + 3 * b) * n + MOD(8 + 3 * b, 8) * n + MOD(8 + 4 + 4 + 2 * b + (8 + 3 * b) * n + MOD(8 + 3 * b, 8) * n, 8)
java arraylist collections linked-list

আমি সর্বদা ব্যবহার করার জন্য সবসময় এক হয়েছে:

List<String> names = new ArrayList<>();

আমি ইন্টারফেসটি পোর্টেবিলিটির জন্য টাইপ নাম হিসাবে ব্যবহার করি, যাতে যখন আমি এই ধরনের প্রশ্ন জিজ্ঞাসা করি তখন আমি আমার কোডটি পুনর্বিবেচনা করতে পারি।

কখন LinkedList ArrayList এবং এর বিপরীতে ব্যবহার করা উচিত?




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

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

আপনি যদি কর্মক্ষমতা দ্বারা অর্থ বোঝা হয় তবে ArrayList শুধুমাত্র পারফরম্যান্সের জন্য একটি ভাল পছন্দ এবং আপনি বিলম্বিততা উপেক্ষা করতে পারেন। আমার কাজে আমার অভিজ্ঞতায় আমি সবচেয়ে খারাপ কেস প্রবণতা উপেক্ষা করতে পারি না।




হ্যাঁ, আমি জানি, এটি একটি প্রাচীন প্রশ্ন, তবে আমি আমার দুটি সেন্টে নিক্ষেপ করবো:

LinkedList প্রায় সবসময় ভুল পছন্দ, কর্মক্ষমতা অনুযায়ী। সেখানে কিছু খুব নির্দিষ্ট অ্যালগরিদম রয়েছে যেখানে লিঙ্কডলিস্ট বলা হয়, তবে এটিগুলি খুব খুব বিরল এবং অ্যালগরিদম সাধারণত বিশেষভাবে লিঙ্কেলস্টের তালিকার মাঝখানে উপাদানগুলির সন্নিবেশ এবং মুছে ফেলার ক্ষমতা নির্ভর করে, একবার আপনি সেখানে নেভিগেট করলে একটি ListIterator সঙ্গে।

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




সঠিক বা ভুল: স্থানীয়ভাবে পরীক্ষা চালান এবং নিজের জন্য সিদ্ধান্ত নিন!

LinkedList চেয়ে LinkedList সম্পাদনা / অপসারণ দ্রুততর।

Array দ্বারা সমর্থিত ArrayList , যা আকার দ্বিগুণ হতে হবে, বড় ভলিউম অ্যাপ্লিকেশন খারাপ।

নীচে প্রতিটি অপারেশন জন্য ইউনিট পরীক্ষার ফলাফল। নমুনা নমনীয় মধ্যে দেওয়া হয়।

Operation                       ArrayList                      LinkedList  

AddAll   (Insert)               101,16719                      2623,29291 

Add      (Insert-Sequentially)  152,46840                      966,62216

Add      (insert-randomly)      36527                          29193

remove   (Delete)               20,56,9095                     20,45,4904

contains (Search)               186,15,704                     189,64,981

এখানে কোডটি রয়েছে:

import org.junit.Assert;
import org.junit.Test;

import java.util.*;

public class ArrayListVsLinkedList {
    private static final int MAX = 500000;
    String[] strings = maxArray();

    ////////////// ADD ALL ////////////////////////////////////////
    @Test
    public void arrayListAddAll() {
        Watch watch = new Watch();
        List<String> stringList = Arrays.asList(strings);
        List<String> arrayList = new ArrayList<String>(MAX);

        watch.start();
        arrayList.addAll(stringList);
        watch.totalTime("Array List addAll() = ");//101,16719 Nanoseconds
    }

    @Test
    public void linkedListAddAll() throws Exception {
        Watch watch = new Watch();
        List<String> stringList = Arrays.asList(strings);

        watch.start();
        List<String> linkedList = new LinkedList<String>();
        linkedList.addAll(stringList);
        watch.totalTime("Linked List addAll() = ");  //2623,29291 Nanoseconds
    }

    //Note: ArrayList is 26 time faster here than LinkedList for addAll()

    ///////////////// INSERT /////////////////////////////////////////////
    @Test
    public void arrayListAdd() {
        Watch watch = new Watch();
        List<String> arrayList = new ArrayList<String>(MAX);

        watch.start();
        for (String string : strings)
            arrayList.add(string);
        watch.totalTime("Array List add() = ");//152,46840 Nanoseconds
    }

    @Test
    public void linkedListAdd() {
        Watch watch = new Watch();

        List<String> linkedList = new LinkedList<String>();
        watch.start();
        for (String string : strings)
            linkedList.add(string);
        watch.totalTime("Linked List add() = ");  //966,62216 Nanoseconds
    }

    //Note: ArrayList is 9 times faster than LinkedList for add sequentially

    /////////////////// INSERT IN BETWEEN ///////////////////////////////////////

    @Test
    public void arrayListInsertOne() {
        Watch watch = new Watch();
        List<String> stringList = Arrays.asList(strings);
        List<String> arrayList = new ArrayList<String>(MAX + MAX / 10);
        arrayList.addAll(stringList);

        String insertString0 = getString(true, MAX / 2 + 10);
        String insertString1 = getString(true, MAX / 2 + 20);
        String insertString2 = getString(true, MAX / 2 + 30);
        String insertString3 = getString(true, MAX / 2 + 40);

        watch.start();

        arrayList.add(insertString0);
        arrayList.add(insertString1);
        arrayList.add(insertString2);
        arrayList.add(insertString3);

        watch.totalTime("Array List add() = ");//36527
    }

    @Test
    public void linkedListInsertOne() {
        Watch watch = new Watch();
        List<String> stringList = Arrays.asList(strings);
        List<String> linkedList = new LinkedList<String>();
        linkedList.addAll(stringList);

        String insertString0 = getString(true, MAX / 2 + 10);
        String insertString1 = getString(true, MAX / 2 + 20);
        String insertString2 = getString(true, MAX / 2 + 30);
        String insertString3 = getString(true, MAX / 2 + 40);

        watch.start();

        linkedList.add(insertString0);
        linkedList.add(insertString1);
        linkedList.add(insertString2);
        linkedList.add(insertString3);

        watch.totalTime("Linked List add = ");//29193
    }


    //Note: LinkedList is 3000 nanosecond faster than ArrayList for insert randomly.

    ////////////////// DELETE //////////////////////////////////////////////////////
    @Test
    public void arrayListRemove() throws Exception {
        Watch watch = new Watch();
        List<String> stringList = Arrays.asList(strings);
        List<String> arrayList = new ArrayList<String>(MAX);

        arrayList.addAll(stringList);
        String searchString0 = getString(true, MAX / 2 + 10);
        String searchString1 = getString(true, MAX / 2 + 20);

        watch.start();
        arrayList.remove(searchString0);
        arrayList.remove(searchString1);
        watch.totalTime("Array List remove() = ");//20,56,9095 Nanoseconds
    }

    @Test
    public void linkedListRemove() throws Exception {
        Watch watch = new Watch();
        List<String> linkedList = new LinkedList<String>();
        linkedList.addAll(Arrays.asList(strings));

        String searchString0 = getString(true, MAX / 2 + 10);
        String searchString1 = getString(true, MAX / 2 + 20);

        watch.start();
        linkedList.remove(searchString0);
        linkedList.remove(searchString1);
        watch.totalTime("Linked List remove = ");//20,45,4904 Nanoseconds
    }

    //Note: LinkedList is 10 millisecond faster than ArrayList while removing item.

    ///////////////////// SEARCH ///////////////////////////////////////////
    @Test
    public void arrayListSearch() throws Exception {
        Watch watch = new Watch();
        List<String> stringList = Arrays.asList(strings);
        List<String> arrayList = new ArrayList<String>(MAX);

        arrayList.addAll(stringList);
        String searchString0 = getString(true, MAX / 2 + 10);
        String searchString1 = getString(true, MAX / 2 + 20);

        watch.start();
        arrayList.contains(searchString0);
        arrayList.contains(searchString1);
        watch.totalTime("Array List addAll() time = ");//186,15,704
    }

    @Test
    public void linkedListSearch() throws Exception {
        Watch watch = new Watch();
        List<String> linkedList = new LinkedList<String>();
        linkedList.addAll(Arrays.asList(strings));

        String searchString0 = getString(true, MAX / 2 + 10);
        String searchString1 = getString(true, MAX / 2 + 20);

        watch.start();
        linkedList.contains(searchString0);
        linkedList.contains(searchString1);
        watch.totalTime("Linked List addAll() time = ");//189,64,981
    }

    //Note: Linked List is 500 Milliseconds faster than ArrayList

    class Watch {
        private long startTime;
        private long endTime;

        public void start() {
            startTime = System.nanoTime();
        }

        private void stop() {
            endTime = System.nanoTime();
        }

        public void totalTime(String s) {
            stop();
            System.out.println(s + (endTime - startTime));
        }
    }


    private String[] maxArray() {
        String[] strings = new String[MAX];
        Boolean result = Boolean.TRUE;
        for (int i = 0; i < MAX; i++) {
            strings[i] = getString(result, i);
            result = !result;
        }
        return strings;
    }

    private String getString(Boolean result, int i) {
        return String.valueOf(result) + i + String.valueOf(!result);
    }
}



1) অনুসন্ধান: অ্যারেলিস্ট অনুসন্ধান ক্রিয়াকলাপ লিংকড্লিস্ট অনুসন্ধান ক্রিয়াকলাপের তুলনায় বেশ দ্রুত। ArrayList এ (int ইন্ডেক্স) পেতে O (1) এর কার্যক্ষমতা দেয় এবং লিঙ্কডলিস্ট কর্মক্ষমতা O (n) হয়।

কারণ: অ্যারেস্টস্ট তার উপাদানগুলির জন্য একটি ইন্ডেক্স ভিত্তিক সিস্টেম বজায় রাখে কারণ এটি অ্যারের তথ্য কাঠামোর ব্যবহার করে যা তালিকাটিতে একটি উপাদান অনুসন্ধানের জন্য এটি দ্রুততর করে তোলে। অন্য দিকে, লিঙ্কডলিস্ট একটি দ্বিগুণ লিঙ্কযুক্ত তালিকা প্রয়োগ করে যা একটি উপাদান অনুসন্ধানের জন্য সমস্ত উপাদানগুলির মাধ্যমে ট্র্যাভার্সাল প্রয়োজন।

2) মুছে ফেলা: লিঙ্কডলিস্ট অপসারণ অপারেশনটি O (1) কর্মক্ষমতা দেয়, যখন অ্যারেস্টিস্ট পরিবর্তনশীল কর্মক্ষমতা দেয়: O (n) সবচেয়ে খারাপ ক্ষেত্রে (প্রথম উপাদানটি সরানোর সময়) এবং O (1) সেরা ক্ষেত্রে (শেষ উপাদানটি সরিয়ে দেওয়ার সময়) ।

উপসংহার: LinkedList উপাদান মুছে ফেলার দ্রুত ArrayList তুলনায় দ্রুত।

কারণ: LinkedList এর প্রতিটি উপাদান দুটি পয়েন্টার (ঠিকানা) বজায় রাখে, যা তালিকার উভয় প্রতিবেশী উপাদানগুলিকে নির্দেশ করে। অতএব অপসারণের শুধুমাত্র নোডের দুটি প্রতিবেশী নোড (উপাদানের) মধ্যে পয়েন্টার অবস্থানের একটি পরিবর্তন প্রয়োজন যা অপসারণ করা যাচ্ছে। যখন ArrayList এ সমস্ত উপাদান সরানো উপাদান দ্বারা তৈরি স্থান পূরণ করতে স্থানান্তর করা প্রয়োজন।

3) পারফরমেন্স সন্নিবেশ: লিঙ্কডলিস্ট অ্যাড পদ্ধতিটি O (1) পারফরম্যান্স দেয়, যখন অ্যারেস্টস্ট সবচেয়ে খারাপ ক্ষেত্রে O (n) দেয়। কারণ মুছে ফেলার জন্য ব্যাখ্যা হিসাবে একই।

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

আছে কয়েক মিল এই শ্রেণীর যা নিম্নরূপ মধ্যে:

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

কখন লিঙ্কডলিস্ট ব্যবহার করবেন এবং কখন অ্যারেস্টিস্ট ব্যবহার করবেন?

1) সন্নিবেশ এবং ব্যাখ্যা অপারেশনগুলির উপরে ব্যাখ্যা করা হয়েছে অ্যার্যলিস্ট (ও (এন) এর তুলনায় লিঙ্কডলিস্টে ভাল কর্মক্ষমতা (O (1)) প্রদান করুন। তাই যদি অ্যাপ্লিকেশনটিতে ঘন ঘন যোগ এবং মুছে ফেলার প্রয়োজন হয় তবে লিঙ্কড্লিস্ট সেরা পছন্দ।

2) অনুসন্ধান (পদ্ধতিটি পান) অ্যারেলিস্টে (ও (1)) দ্রুত থাকে তবে লিংকড্লিস্ট (ও (এন)) তে নয় তবে যদি অপারেশন এবং আরও অনুসন্ধান অপারেশনগুলির প্রয়োজনীয়তা কম থাকে এবং সরানো হয় তবে অ্যারিস্টিস্ট আপনার সেরা বেট হবে।




লিংকডলিস্টের লেখক যিহোশূয় ব্লোক:

কেউ আসলে লিঙ্কডলিস্ট ব্যবহার করে? আমি এটা লিখেছি, এবং আমি এটা ব্যবহার না।

লিংক: https://twitter.com/joshbloch/status/583813919019573248

অন্যান্য উত্তর হিসাবে তথ্যবহুল না হওয়ার জন্য আমি দুঃখিত, কিন্তু আমি মনে করি এটি সবচেয়ে আকর্ষণীয় এবং স্ব-ব্যাখ্যামূলক হবে।




আমি জানি এটি একটি পুরানো পোস্ট, কিন্তু আমি বিশ্বাস করি না যে কেউ এই LinkedListপ্রয়োগগুলিকে উল্লেখ করে না Deque। শুধু Deque(এবং Queue) মধ্যে পদ্ধতি তাকান ; আপনি একটি ন্যায্য তুলনা চাই, চলমান চেষ্টা LinkedListবিরুদ্ধে ArrayDequeএবং একটি বৈশিষ্ট্য-জন্য-বৈশিষ্ট্য তুলনা না।




এর প্যারামিটার নীচের লিঙ্কডলিস্ট এবং ArrayList wrt তুলনা করা যাক:

1. বাস্তবায়ন

ArrayList তালিকা ইন্টারফেসের resizable অ্যারে বাস্তবায়ন হয়, যখন

LinkedList তালিকা ইন্টারফেস দ্বিগুণ লিঙ্কযুক্ত তালিকা বাস্তবায়ন।

2. পারফরম্যান্স

  • পেতে (int সূচক) বা অনুসন্ধান অপারেশন

    ArrayList পেতে (int সূচী) অপারেশন ধ্রুবক সময় অর্থাত্ O (1) সময়

    LinkedList পেতে (int সূচক) অপারেশন রান সময় হে (এন)।

    পিছনে কারণ ArrayList দ্রুত LinkedList চেয়ে হচ্ছে, যে ArrayList যেমন অভ্যন্তরীণভাবে, একটি বিন্যাস ডাটা স্ট্রাকচার ব্যবহার অন্যদিকে তার উপাদানের জন্য একটি সূচক ভিত্তিক সিস্টেমের ব্যবহার করে

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

  • সন্নিবেশ () বা যোগ (অবজেক্ট) অপারেশন

    লিঙ্কডলিস্টের সন্নিবেশগুলি সাধারণত অ্যার্যলিস্টের তুলনায় দ্রুত। LinkedList যোগ বা সন্নিবেশ মধ্যে হে (1) অপারেশন।

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

  • অপসারণ (int) অপারেশন

    লিংকডলিস্ট-এ অপারেশন সরান সাধারণত অ্যার্যলিস্ট অর্থাৎ ও (এন) হিসাবে একই।

    ইন LinkedList , দুই ওভারলোড অপসারণ পদ্ধতি। এক অপসারণ করা হয় () কোনও প্যারামিটার ছাড়াই যা তালিকার প্রধানটি সরানো এবং ধ্রুবক সময় O (1) তে রান করে। লিংকডলিস্টের অন্যান্য ওভারলোড হওয়া অপসারণ পদ্ধতিটি সরিয়ে ফেলা (int) বা সরিয়ে ফেলা (বস্তু) যা বস্তু বা প্রান্তটিকে পরামিতি হিসাবে সরিয়ে দেয়। এই পদ্ধতিটি লিঙ্কডলিস্টটিকে ট্র্যাক করে এবং অবজেক্টটি খুঁজে পায় এবং এটি মূল তালিকা থেকে আনলক করে। সুতরাং এই পদ্ধতি রানটাইম হে (এন) হয়।

    যখন ArrayList অপসারণ (int) পদ্ধতিতে পুরানো অ্যারের থেকে উপাদানগুলি নতুন আপডেট করা অ্যারেতে অনুলিপি করা হয়, তাই এটির রানটাইম হল O (n)।

3. বিপরীত বিভাজক

লিঙ্কডলিস্টটি ঊর্ধ্বমুখী ইন্টারটার্টার () ব্যবহার করে বিপরীত দিকে পুনরাবৃত্তি করা যেতে পারে

ArrayList এ কোন অবতরণকারী () নেই , সুতরাং আমাদের বিপরীত দিকে ArrayList উপর পুনরাবৃত্তি করার জন্য আমাদের নিজস্ব কোড লিখতে হবে।

4. প্রাথমিক ক্যাপাসিটি

যদি কনস্ট্রাক্টর ওভারলোড করা না হয়, তবে অ্যারেস্টিস্ট প্রাথমিক ক্ষমতা 10 এর একটি খালি তালিকা তৈরি করে

LinkedList শুধুমাত্র কোনো প্রাথমিক ক্ষমতা ছাড়া খালি তালিকা গঠন করে।

5. মেমরি ওভারহেড

লিঙ্কেডলিস্টের মেমরি ওভারহেড অ্যারেলিস্টের তুলনায় আরও বেশি , লিঙ্কডলিস্টের একটি নোড হিসাবে পরবর্তী এবং পূর্ববর্তী নোডের ঠিকানাগুলি বজায় রাখতে প্রয়োজন। যদিও

ইন ArrayList প্রতিটি সূচক শুধুমাত্র প্রকৃত বস্তু (ডেটা) ঝুলিতে।

Source







এটা তালিকা উপর আপনি আরো কাজ করবে কি উপর নির্ভর করে।

ArrayListএকটি সূচী মান অ্যাক্সেস দ্রুত। বস্তু সন্নিবেশ বা মুছে ফেলার সময় এটি আরও খারাপ।

আরো জানতে, অ্যারে এবং লিঙ্ক তালিকাগুলির মধ্যে পার্থক্য সম্পর্কে আলোচনা করে এমন কোনও নিবন্ধ পড়ুন।




একটি লিঙ্কযুক্ত তালিকার একটি গুরুত্বপূর্ণ বৈশিষ্ট্য (যা আমি অন্য উত্তরে পড়িনি) দুটি তালিকার সংযোজন। একটি অ্যারের সাথে এটি একটি লিঙ্কযুক্ত তালিকা সহ O (n) (+ কিছু পুনর্বহালের ওভারহেড) হয় এটি শুধুমাত্র O (1) বা O (2) ;-)

গুরুত্বপূর্ণ : জাভা এর LinkedListজন্য এটি সত্য নয়! জাভা লিঙ্ক তালিকা জন্য একটি দ্রুত কনক্যাট পদ্ধতি আছে দেখুন ?




ArrayListএবং LinkedListউভয় প্রয়োগ List interfaceএবং তাদের পদ্ধতি এবং ফলাফল প্রায় অভিন্ন। তবে প্রয়োজনীয়তার উপর নির্ভর করে অন্যের উপর আরও ভাল করে তাদের মধ্যে কয়েকটি পার্থক্য রয়েছে।

ArrayList ভি লিঙ্কডলিস্ট

1) Search: ArrayListঅনুসন্ধান অপারেশন অনুসন্ধান অপারেশন তুলনায় বেশ দ্রুত LinkedListget(int index)মধ্যে ArrayListকর্মক্ষমতা দেয় O(1)যখন LinkedListহয় কর্মক্ষমতা O(n)

Reason: ArrayListসূচী ভিত্তিক সিস্টেমটিকে তার উপাদানগুলির জন্য বজায় রাখে কারণ এটি অ্যারে তথ্য গঠনকে ব্যবহার করে যা এটি তালিকায় একটি উপাদান অনুসন্ধানের জন্য দ্রুততর করে তোলে। অন্য দিকে LinkedListদ্বিগুণ লিঙ্কযুক্ত তালিকা প্রয়োগ করে যা একটি উপাদান অনুসন্ধানের জন্য সমস্ত উপাদানগুলির মাধ্যমে ট্রাভেরসাল প্রয়োজন।

2) Deletion: LinkedListঅপসারণ অপারেশন দেয় O(1)যখন ArrayListপরিবর্তনশীল কর্মক্ষমতা দেয়: O(n)সবচেয়ে খারাপ ক্ষেত্রে (প্রথম উপাদান অপসারণের সময়) এবং O(1)ভাল ক্ষেত্রে (শেষ উপাদান অপসারণের সময়)।

উপসংহার: LinkedList উপাদান মুছে ফেলার দ্রুত ArrayList তুলনায় দ্রুত।

কারণ: লিঙ্কেডলিস্টের প্রতিটি উপাদান দুটি পয়েন্টার (ঠিকানা) বজায় রাখে যা তালিকাতে উভয় প্রতিবেশী উপাদানকে নির্দেশ করে। অতএব অপসারণের শুধুমাত্র নোডের দুটি প্রতিবেশী নোড (উপাদানের) মধ্যে পয়েন্টার অবস্থান পরিবর্তন প্রয়োজন যা অপসারণ করা যাচ্ছে। যখন ArrayList এ সমস্ত উপাদান সরানো উপাদান দ্বারা তৈরি স্থান পূরণ করতে স্থানান্তর করা প্রয়োজন।

3) সবচেয়ে খারাপ ক্ষেত্রে দেয় যখন Inserts Performance: LinkedListপদ্ধতি যোগ O(1)কর্মক্ষমতা ArrayListদেয় O(n)। কারণ মুছে ফেলার জন্য ব্যাখ্যা হিসাবে একই।

4) প্রতিবেশী নোডের জন্য উপাদান তথ্য এবং দুটি পয়েন্টার বজায় রাখার Memory Overhead: ArrayListসময় সূচী এবং উপাদান তথ্য LinkedListবজায় রাখে

সুতরাং তুলনামূলকভাবে LinkedList মধ্যে মেমরি খরচ উচ্চ।

নিম্নরূপ এই ক্লাসগুলির মধ্যে কয়েকটি মিল রয়েছে:

  • অ্যারেস্টিস্ট এবং লিঙ্কডলিস্ট উভয় তালিকা ইন্টারফেস বাস্তবায়ন হয়।
  • তারা উভয় উপাদান সন্নিবেশ ক্রম বজায় রাখে যার মানে হল অ্যারেস্টিস্ট এবং লিঙ্কডলিস্ট উপাদানগুলি প্রদর্শন করার সময় ফলাফল সেটটি একই ক্রম থাকবে যার মধ্যে তালিকা তালিকাতে ঢোকানো হয়েছে।
  • এই উভয় ক্লাসগুলি অ-সিঙ্ক্রোনাইজড এবং সংগ্রহগুলি.SynchronizedList পদ্ধতি ব্যবহার করে স্পষ্টভাবে সিঙ্ক্রোনাইজ করা যেতে পারে।
  • iteratorএবং listIteratorএই শ্রেণীর দ্বারা ফিরে হয় fail-fast(যদি তালিকা গঠনের দিক ছাড়া যে কোনো সময় রুপান্তরিত করা হয়েছে কোন ভাবেই পর পুনরুক্তিকারীর তৈরি করা হয় iterator'sনিজের অপসারণ বা পদ্ধতি যোগ করুন, পুনরুক্তিকারীর হবে throwএকটি ConcurrentModificationException)।

কখন লিঙ্কডলিস্ট ব্যবহার করবেন এবং কখন অ্যারেস্টিস্ট ব্যবহার করবেন?

  • সন্নিবেশ উপরে বর্ণিত এবং অপসারণ হিসাবে অপারেশন ভাল পারফরম্যান্স দিতে (O(1))মধ্যে LinkedListতুলনায় ArrayList(O(n))

    তাই যদি অ্যাপ্লিকেশনটিতে ঘন ঘন যোগ এবং মুছে ফেলার প্রয়োজন হয় তবে লিঙ্কডলিস্ট একটি সর্বোত্তম পছন্দ।

  • অনুসন্ধান ( get method) অপারেশন দ্রুত Arraylist (O(1))কিন্তু নাLinkedList (O(n))

    তাই যদি কম যোগ এবং অপারেশন এবং আরো অনুসন্ধান অপারেশন প্রয়োজনীয়তা অপসারণ করা হয়, ArrayList আপনার সেরা বাজি হবে।




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

তত্ত্ব অনুসারে, লিঙ্কেডলিস্টটির জন্য একটি O (1) আছে add(E element)

এছাড়াও একটি তালিকার মাঝখানে একটি উপাদান যোগ করা খুব দক্ষ হতে হবে।

প্র্যাকটিস খুবই ভিন্ন, লিঙ্কডলিস্ট একটি ক্যাশে হোস্টাইল ডেটা গঠন। কর্মক্ষমতা পিওভি থেকে - ক্যাশে-বন্ধুত্বপূর্ণLinkedList তুলনায় ভাল সঞ্চালিত হতে পারে যেখানে খুব সামান্য ক্ষেত্রে আছে । ArrayList

এখানে র্যান্ডম অবস্থানে উপাদান অন্তর্ভুক্ত একটি বেঞ্চমার্ক পরীক্ষার ফলাফল। যেহেতু আপনি দেখতে পারেন -, অ্যারে তালিকা অনেক বেশি দক্ষ যদি যদিও তত্ত্ব তালিকা মাঝখানে প্রতিটি সন্নিবেশ "স্থানান্তর" প্রয়োজন হবে এন পরে অ্যারের উপাদানের (নিম্ন মান আরও ভাল হয়):

পরবর্তী প্রজন্মের হার্ডওয়্যার (বৃহত্তর, আরও দক্ষ ক্যাশে) -তে কাজ করা - ফলাফল আরও বেশি সংখ্যাগরিষ্ঠ:

LinkedList একই কাজ সম্পাদন করতে আরো অনেক সময় লাগে। source উত্স কোড

এই জন্য দুটি প্রধান কারণ আছে:

  1. প্রধানত - যে নোড LinkedListমেমরি জুড়ে এলোমেলোভাবে বিক্ষিপ্ত হয়। RAM ("র্যান্ডম অ্যাক্সেস মেমরি") সত্যিই র্যান্ডম নয় এবং ক্যাশে আনতে মেমরির ব্লকগুলি প্রয়োজন। এই অপারেশনটি সময় নেয়, এবং যখন এই ধরনের ঘন ঘন ঘন ঘন ঘটে - ক্যাশে মেমরি পৃষ্ঠাগুলি প্রতিবার প্রতিস্থাপিত করতে হবে -> ক্যাশ মিস -> ক্যাশ কার্যকর নয়। ArrayListউপাদানগুলি ক্রমাগত মেমরিতে সংরক্ষণ করা হয় - যা ঠিক আধুনিক CPU আর্কিটেকচারের জন্য উপযুক্ত হয়।

  2. মাধ্যমিক LinkedList ব্যাক / ফরোয়ার্ড পয়েন্টার রাখা প্রয়োজন, যা মানে মান প্রতি মেমরি খরচ 3 বার তুলনায় সংরক্ষিত ArrayList

DynamicIntArray , DynamicIntArray একটি কাস্টম DynamicIntArray বাস্তবায়ন হোল্ডিং Int(আদিম টাইপ) এবং বস্তু নয় - সুতরাং সমস্ত তথ্য সত্যিই পাশাপাশি সঞ্চিত হয় - তাই আরও দক্ষ।

মনে রাখার একটি মূল উপাদান হল মেমরি ব্লক আনতে খরচ, একক মেমরি সেল অ্যাক্সেসের খরচ থেকে বেশি গুরুত্বপূর্ণ। এই কারণে পাঠকের 1 এমবি ক্রমিক মেমরিটি মেমরির বিভিন্ন ব্লকগুলি থেকে এই পরিমাণ পরিমাণ তথ্য পড়ার চেয়ে x400 গুণ দ্রুততর হয়:

Latency Comparison Numbers (~2012)
----------------------------------
L1 cache reference                           0.5 ns
Branch mispredict                            5   ns
L2 cache reference                           7   ns                      14x L1 cache
Mutex lock/unlock                           25   ns
Main memory reference                      100   ns                      20x L2 cache, 200x L1 cache
Compress 1K bytes with Zippy             3,000   ns        3 us
Send 1K bytes over 1 Gbps network       10,000   ns       10 us
Read 4K randomly from SSD*             150,000   ns      150 us          ~1GB/sec SSD
Read 1 MB sequentially from memory     250,000   ns      250 us
Round trip within same datacenter      500,000   ns      500 us
Read 1 MB sequentially from SSD*     1,000,000   ns    1,000 us    1 ms  ~1GB/sec SSD, 4X memory
Disk seek                           10,000,000   ns   10,000 us   10 ms  20x datacenter roundtrip
Read 1 MB sequentially from disk    20,000,000   ns   20,000 us   20 ms  80x memory, 20X SSD
Send packet CA->Netherlands->CA    150,000,000   ns  150,000 us  150 ms

উত্স: ল্যাটেন্সি নম্বর প্রত্যেক প্রোগ্রামার জানতে হবে

শুধু বিন্দুটিকে আরও স্পষ্ট করে তুলতে, তালিকাটির শুরুতে উপাদান যুক্ত করার বেঞ্চমার্কটি পরীক্ষা করুন। এটি একটি ব্যবহার-কেস যেখানে ইন-তত্ত্ব, LinkedListসত্যিই উজ্জ্বল ArrayListহওয়া উচিত , এবং দরিদ্র বা এমনকি খারাপ-কেস ফলাফল উপস্থিত হওয়া উচিত:

দ্রষ্টব্য: এটি সি ++ স্টডি লিবের একটি বেঞ্চমার্ক, তবে আমার আগের অভিজ্ঞতাটি সি ++ এবং জাভা ফলাফলগুলি একই রকম দেখাচ্ছে। সোর্স কোড

মেমরি একটি ক্রমবর্ধমান বাল্ক অনুলিপি একটি আধুনিক CPUs দ্বারা অপ্টিমাইজ করা হয় - তত্ত্ব পরিবর্তন এবং আসলে, আবার, ArrayList/ Vectorআরো দক্ষ

ক্রেডিট: এখানে পোস্ট করা সমস্ত benchmarks কেজেল হেডস্ট্রম দ্বারা তৈরি করা হয় । এমনকি আরও তথ্য তার ব্লগে পাওয়া যাবে




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

একটি অ্যারেস্টিস্টে, আপনি O (1) এ উপাদানটি পেতে পারেন, তবে আসলে কোনও সরানো বা সন্নিবেশ করা এটি O (n) করে তোলে কারণ নিম্নলিখিত সমস্ত উপাদানগুলি পরিবর্তন করতে হবে।

লিঙ্কেডলিস্টে, এটি আসলেই পছন্দসই উপাদানটি পেতে O (n) নেয়, কারণ আমরা যত তাড়াতাড়ি শুরুতে শুরু করি, যতক্ষণ না আমরা পছন্দসই সূচী পৌঁছায়। প্রকৃতপক্ষে অপসারণ বা সন্নিবেশ করা ধ্রুবক, কারণ আমরা কেবল সরিয়ে () এবং সন্নিবেশ () এর জন্য 2 রেফারেন্সের জন্য 1 রেফারেন্স পরিবর্তন করতে হবে।

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

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




আমি এখানে দেখেছি পরীক্ষা এক একবার শুধুমাত্র পরীক্ষা সঞ্চালিত। কিন্তু আমি লক্ষ্য করেছি যে আপনাকে এই পরীক্ষাগুলি অনেক বার চালাতে হবে এবং অবশেষে তাদের সময়গুলি একত্রিত হবে। মূলত JVM আপ উষ্ণ আপ প্রয়োজন। আমার বিশেষ ব্যবহারের ক্ষেত্রে আমাকে প্রায় 500 টি আইটেমের মধ্যে শেষ হওয়া আইটেমগুলিকে যোগ / অপসারণ করতে হবে। আমার পরীক্ষায় LinkedListদ্রুত বেরিয়ে আসে, LinkedListপ্রায় 50,000 এনএস ArrayList-এ আসছে এবং প্রায় 90,000 এনএস এ আসছে ... দিতে বা নিতে। নীচের কোড দেখুন।

public static void main(String[] args) {
    List<Long> times = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        times.add(doIt());
    }
    System.out.println("avg = " + (times.stream().mapToLong(x -> x).average()));
}

static long doIt() {
    long start = System.nanoTime();
    List<Object> list = new LinkedList<>();
    //uncomment line below to test with ArrayList
    //list = new ArrayList<>();
    for (int i = 0; i < 500; i++) {
        list.add(i);
    }

    Iterator it = list.iterator();
    while (it.hasNext()) {
        it.next();
        it.remove();
    }
    long end = System.nanoTime();
    long diff = end - start;
    //uncomment to see the JVM warmup and get faster for the first few iterations
    //System.out.println(diff)
    return diff;
}





Related