জাভা 8-এ, অ্যারেলিস্টের ডিফল্ট ক্ষমতা এখন শূন্য কেন?


94

আমার স্মরণ হিসাবে, জাভা 8 এর আগে, এর ডিফল্ট ক্ষমতা ArrayListছিল 10 ছিল।

আশ্চর্যজনকভাবে, ডিফল্ট (অকার্যকর) নির্মাণকারী সম্পর্কে মন্তব্য এখনও বলে: Constructs an empty list with an initial capacity of ten.

থেকে ArrayList.java:

/**
 * Shared empty array instance used for default sized empty instances. We
 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
 * first element is added.
 */
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

...

/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

উত্তর:


106

প্রযুক্তিগতভাবে, এটি 10শূন্য নয়, আপনি যদি ব্যাকিং অ্যারের অলস সূচনা করার জন্য স্বীকার করেন। দেখা:

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

কোথায়

/**
 * Default initial capacity.
 */
private static final int DEFAULT_CAPACITY = 10;

আপনি যা উল্লেখ করছেন তা হ'ল শূন্য আকারের প্রাথমিক অ্যারে অবজেক্ট যা প্রাথমিকভাবে সমস্ত শূন্য ArrayListঅবজেক্টের মধ্যে ভাগ করা হয় । অর্থাৎ এর সক্ষমতা অলসভাবে10 গ্যারান্টিযুক্ত , একটি অপ্টিমাইজেশন যা জাভা 7 এও উপস্থিত।

স্বীকার করা, নির্মাতা চুক্তি পুরোপুরি সঠিক নয়। সম্ভবত এটি এখানে বিভ্রান্তির উত্স।

পটভূমি

এখানে মাইক ডিউগুয়ের একটি ইমেল রয়েছে

আমি খালি অ্যারেলিস্ট এবং হ্যাশম্যাপ প্যাচের একটি আপডেট সংস্করণ পোস্ট করেছি।

http://cr.openjdk.java.net/~mduigou/JDK-7143928/1/webrev/

এই সংশোধিত বাস্তবায়ন শ্রেণীর জন্য কোনও নতুন ক্ষেত্রের পরিচয় দেয় না । অ্যারেলিস্টের জন্য ব্যাকিং অ্যারের অলস বরাদ্দটি তখনই ঘটে যখন তালিকাটি ডিফল্ট আকারে তৈরি করা হয়। আমাদের পারফরম্যান্স বিশ্লেষণ দল অনুসারে, অ্যারেলিস্টের প্রায় 85% দৃষ্টান্তটি ডিফল্ট আকারে তৈরি করা হয় তাই এই অপ্টিমাইজেশানটি অত্যধিক সংখ্যক ক্ষেত্রে বৈধ হবে।

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

থেকে: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013- এপ্রিল / 015585.html


4
মতে bugs.java.com/bugdatabase/view_bug.do?bug_id=7143928 এটা গাদা ব্যবহার এবং উন্নত প্রতিক্রিয়া বার কমাতে বাড়ে (দুই appications জন্য সংখ্যা দেখানো হয়)
থমাস Kläger

4
@ খেলউড: অ্যারেলিস্ট তার জাভাডোকের বাইরে অন্য কিছু করার ক্ষমতাটি সত্যই "প্রতিবেদন" করে না: এর কোনও getCapacity()পদ্ধতি বা এ জাতীয় কিছু নেই। (এটি বলেছিল, এরকম কিছু ensureCapacity(7)ডিফল্ট-
আরম্ভিত অ্যারেলিস্টের

11
ভাল খনন। ডিফল্ট প্রাথমিক ক্ষমতা প্রকৃতপক্ষে শূন্য নয়, তবে 10, ডিফল্ট কেসটি অলসভাবে একটি বিশেষ কেস হিসাবে বরাদ্দ করা হয়। আপনি যদি বার বার ArrayListনন-আরগ কনস্ট্রাক্টর বনাম কনস্ট্রাক্টরের শূন্যের পাস দিয়ে তৈরির সাথে উপাদানগুলি যুক্ত করেন intএবং আপনি যদি অভ্যন্তরীণ অ্যারের আকারের প্রতিফলন বা ডিবাগারে তাকান তবে আপনি এটি পর্যবেক্ষণ করতে পারেন। ডিফল্ট ক্ষেত্রে অ্যারে 1.5x বৃদ্ধির হার অনুসরণ করে 0 থেকে 10 এবং তারপরে 15, 22 এ লাফ দেয়। শূন্যকে প্রাথমিক সামর্থ্য হিসাবে পাস করা 0 থেকে 1, 2, 3, 4, 6, 9, 13, 19 থেকে বৃদ্ধির ফলস্বরূপ ....
স্টুয়ার্ট

14
আমি মাইক ডুইগু, পরিবর্তনের লেখক এবং উদ্ধৃত ইমেল এবং আমি এই বার্তাটি অনুমোদন করছি। St স্টুয়ার্ট বলেছে যে অনুপ্রেরণা মূলত পারফরম্যান্সের চেয়ে স্পেস সাশ্রয় নিয়ে ছিল যদিও ব্যাকিং অ্যারের তৈরি ঘন ঘন ঘন ঘন এড়িয়ে যাওয়ার কারণে সামান্য পারফরম্যান্স সুবিধাও রয়েছে।
মাইক ডিউগু

4
@ এ্যাসেলিয়াস:; ^) না, এখনও এটির জায়গা রয়েছে কারণ একা একা emptyList()বেশ কয়েকটি খালি ArrayListদৃষ্টান্তের চেয়ে কম স্মৃতি গ্রহণ করে । এটি এখনই কম গুরুত্বপূর্ণ এবং সুতরাং প্রতিটি জায়গায় প্রয়োজন হয় না , বিশেষত পরবর্তী সময়ে উপাদান যুক্ত করার উচ্চতর সম্ভাবনাযুক্ত জায়গাগুলিতে নয়। এছাড়াও মনে রাখবেন যে আপনি কখনো কখনো চান একটি অপরিবর্তনীয় খালি তালিকা এবং তারপর emptyList()যেতে উপায়।
হলগার

24

জাভাতে অ্যারেলিস্টের 8 ডিফল্ট ধারণক্ষমতা 0 হয় যতক্ষণ না আমরা অ্যারেলিস্ট অবজেক্টে কমপক্ষে একটি অবজেক্ট যোগ না করে (আপনি এটিকে অলস সূচনা বলতে পারেন)।

এখন প্রশ্ন হচ্ছে জাভা 8 এ এই পরিবর্তনটি করা হয়েছে কেন?

উত্তর হ'ল মেমরির খরচ সঞ্চয় করা। কয়েক মিলিয়ন অ্যারে তালিকা অবজেক্ট রিয়েল টাইম জাভা অ্যাপ্লিকেশনগুলিতে তৈরি করা হয়। 10 টি অবজেক্টের ডিফল্ট আকারের অর্থ হ'ল আমরা সৃষ্টিতে অন্তর্নিহিত অ্যারেটির জন্য 10 পয়েন্টার (40 বা 80 বাইট) বরাদ্দ করি এবং সেগুলি নাল দিয়ে পূরণ করি। একটি খালি অ্যারে (নাল দিয়ে ভরা) প্রচুর স্মৃতি দখল করে।

অলস সূচনাটি এই মেমরির খরচটিকে মুহূর্ত পর্যন্ত স্থগিত করে আপনি আসলে অ্যারে তালিকাটি ব্যবহার করবেন।

সহায়তার জন্য নীচে কোড দেখুন।

ArrayList al = new ArrayList();          //Size:  0, Capacity:  0
ArrayList al = new ArrayList(5);         //Size:  0, Capacity:  5
ArrayList al = new ArrayList(new ArrayList(5)); //Size:  0, Capacity:  0
al.add( "shailesh" );                    //Size:  1, Capacity: 10

public static void main( String[] args )
        throws Exception
    {
        ArrayList al = new ArrayList();
        getCapacity( al );
        al.add( "shailesh" );
        getCapacity( al );
    }

    static void getCapacity( ArrayList<?> l )
        throws Exception
    {
        Field dataField = ArrayList.class.getDeclaredField( "elementData" );
        dataField.setAccessible( true );
        System.out.format( "Size: %2d, Capacity: %2d%n", l.size(), ( (Object[]) dataField.get( l ) ).length );
}

Response: - 
Size:  0, Capacity:  0
Size:  1, Capacity: 10

জাভা 8-তে অ্যারেলিস্টের নিবন্ধ ডিফল্ট ক্ষমতা এটি বিশদে ব্যাখ্যা করে।


7

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

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


সম্পর্কে খুব ভাল পয়েন্ট addAll()। প্রথম ম্যালোককে ঘিরে দক্ষতা বাড়ানোর জন্য এটি আর একটি সুযোগ।
কেভিনার্পে

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

3

প্রশ্ন 'কেন?'।

মেমরি প্রোফাইলিং পরিদর্শন (উদাহরণস্বরূপ ( https://www.yourkit.com/docs/java/help/inspections_mem.jsp#sparse_arrays ) দেখায় যে খালি (নালায় ভরা) অ্যারেগুলি প্রচুর পরিমাণে মেমরি দখল করে।

10 টি অবজেক্টের ডিফল্ট আকারের অর্থ হ'ল আমরা সৃষ্টিতে অন্তর্নিহিত অ্যারেটির জন্য 10 পয়েন্টার (40 বা 80 বাইট) বরাদ্দ করি এবং সেগুলি নাল দিয়ে পূরণ করি। বাস্তব জাভা অ্যাপ্লিকেশনগুলি কয়েক মিলিয়ন অ্যারে তালিকা তৈরি করে।

প্রবর্তিত পরিবর্তনটি actually ডাব্লু এই মেমরির ব্যবহারটি মুহূর্ত পর্যন্ত স্থগিত করে আপনি আসলে অ্যারে তালিকা ব্যবহার করবেন।


দয়া করে "বর্জ্য" দিয়ে "গ্রাস" সংশোধন করুন। আপনি যে লিঙ্কটি সরবরাহ করেছেন তা বোঝায় না যে তারা সর্বত্র মেমোরি গাব্বল করা শুরু করে, কেবল নাল উপাদানগুলির সাথে অ্যারেগুলি তাদের জন্য বরাদ্দকৃত স্মৃতিটিকে অপ্রয়োজনীয়ভাবে নষ্ট করে দেয়। "গ্রাহক" বলতে বোঝায় যে তারা যাদুকরভাবে তাদের বরাদ্দের বাইরে স্মৃতি ব্যবহার করে, যা এটি নয়।
mechalynx

1

উপরের প্রশ্নের পরে আমি জাভা 8 এর অ্যারেলিস্ট ডকুমেন্টটি দিয়ে গিয়েছিলাম found আমি ডিফল্ট আকারটি এখনও 10 টি পেয়েছি।

দয়া করে নীচে দেখুন


0

জাভা 8 এ অ্যারেলিস্টের ডিফল্ট আকারটি 10 ​​টি স্টিল 10 J জাভা 8-এ কেবলমাত্র পরিবর্তনটি হ'ল যদি কোনও কোডার যদি 10 টিরও কম উপাদান যুক্ত করে তবে অবশিষ্ট অ্যারেলিস্ট ফাঁকা স্থানগুলি নালকে নির্দিষ্ট করা হয় না। এটি বলার কারণ আমি নিজেই এই পরিস্থিতির মধ্য দিয়ে গেছি এবং গ্রহনটি আমাকে জাভা 8 এর এই পরিবর্তনের দিকে নজর দিয়েছে।

নীচের স্ক্রিনশটটি দেখে আপনি এই পরিবর্তনকে ন্যায়সঙ্গত করতে পারেন। এটিতে আপনি দেখতে পাচ্ছেন অ্যারেলিস্টের আকারটি বস্তুতে 10 হিসাবে নির্দিষ্ট করা হয়েছে [10] তবে প্রদর্শিত উপাদানের সংখ্যা কেবল 7. টি Rest জাভা 7 এর নীচে স্ক্রিনশটটি কেবলমাত্র একটি একক পরিবর্তনের সাথে একই যা নাল মান উপাদানগুলিও প্রদর্শিত হয় যার জন্য কোডার নাল মানগুলি পরিচালনা করার জন্য কোড লিখতে হবে যদি তিনি জাভা 8 তে এই অ্যারেটি সরানো হয় তবে সম্পূর্ণ অ্যারে তালিকার পুনরাবৃত্তি করছে rating কোডার / বিকাশকারী প্রধান।

স্ক্রিন শট লিঙ্ক।

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