জাভাতে অ্যারে বা তালিকা। কোনটি দ্রুত?


351

জাভাতে সিরিয়ালি অ্যাক্সেস করতে আমাকে হাজার হাজার স্ট্রিং স্মৃতিতে রাখতে হবে। আমি কি এগুলিকে একটি অ্যারেতে সঞ্চয় করব বা আমার কোনও ধরণের তালিকা ব্যবহার করা উচিত?

যেহেতু অ্যারে সমস্ত ডেটা মেমরির একটি অবিচ্ছিন্ন অংশে রাখে (তালিকাগুলির বিপরীতে), তাই হাজারে স্ট্রিং সংরক্ষণ করার জন্য কোনও অ্যারের ব্যবহার কী সমস্যার সৃষ্টি করবে?


5
"অ্যারে যেহেতু সমস্ত ডেটা মেমরির সংলগ্ন অংশে রাখে" জাভাটির জন্য এটি ব্যাক আপ করার জন্য আপনার কাছে কি কোনও প্রকারের উদ্ধৃতি দেওয়া আছে?
ম্যাট বি

1
কোন ম্যাট নেই। আমি সি এর জন্য এটি জানি আমি ধারণা করছি জাভা একই পদ্ধতি ব্যবহার করবে।
euphoria83

আমি সন্দেহ করি যে এটি তাদের স্মৃতির একক অংশে রাখবে।
ফরটিয়রুনার

3
এমনকি এটি মেমরির একক ব্লক হলেও এটি কেবলমাত্র 1000 * 4 = 4kb মূল্যবান হতে পারে, যা খুব বেশি স্মৃতি নয়।
কুকি অফফোর্টুন

3
@ ম্যাটটিবি সিএস জুড়েই 'অ্যারে' এর অর্থ। কোন উদ্ধৃতি আবশ্যক। অ্যারে দৈর্ঘ্যের ক্ষেত্রে জেএলএস এবং [জেভিএম স্পেস] () এর অ্যারে দৈর্ঘ্যের অসংখ্য উল্লেখ কেবলমাত্র বোধগম্য।
মারকুইস

উত্তর:


358

আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি কোনও প্রোফাইলার পরীক্ষা করার জন্য ব্যবহার করুন যা দ্রুত।

আমার ব্যক্তিগত মতামতটি হল আপনার তালিকাগুলি ব্যবহার করা উচিত।

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


2
@ ফোর্টরিউনার - আপনার অভিজ্ঞতা থেকে, অ্যাবস্ট্রাকশন এবং কাঁচা ডেটা ফর্মগুলির মধ্যে জাভাতে এমন কোনও পছন্দ আছে যা পারফরম্যান্সে উল্লেখযোগ্য পার্থক্য করে?
euphoria83

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

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

4
মনে রাখবেন যে প্রোফাইলার ফলাফলগুলি কেবল জাভা প্ল্যাটফর্মের জন্য বৈধ যা আপনি বিপরীতে প্রোফাইলার চালাচ্ছেন। যা আপনার গ্রাহকদের চেয়ে আলাদা হতে পারে।
মিক্কেল লাক্কে

4
কার্যকর জাভা তাদের তালিকাগুলির সুপারিশ করে যাতে তারা এপিআই আন্তঃব্যবহারযোগ্যতাতে সহায়তা করে এবং প্রকার সুরক্ষার সাথে আরও সুরক্ষিত হয়।
juanmf

164

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

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

অ্যাবস্ট্রাক্ট ডেটা টাইপের এই পৃথকীকরণ এবং নির্দিষ্ট প্রয়োগটি অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিংয়ের অন্যতম মূল বিষয়।

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

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

যেহেতু অ্যারে সমস্ত ডেটা মেমরির একটি অবিচ্ছিন্ন অংশে রাখে (তালিকাগুলির বিপরীতে), তাই হাজারে স্ট্রিং সংরক্ষণ করার জন্য কোনও অ্যারের ব্যবহার কী সমস্যার সৃষ্টি করবে?

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


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

6
আপনি এখানে ডায়নামিক বাইন্ডিংয়ের মূল্য পরিশোধ করেন না?
উরি

2
আমি অনুমান করতে পারি অ্যারেলিস্টে যুক্তি ও (এন) নয়, একাধিকবার যুক্ত করার সময় কিছুটা অমোরিয়াইজেশন এফেক্ট থাকতে হবে, উদাহরণস্বরূপ মাত্র 1 টি বাড়ানোর পরিবর্তে ক্ষমতা দ্বিগুণ করা হয়েছে
zedoo

@জেডো আমার মনে হয় এগুলি মধ্যবর্তী স্থানে যোগ এবং বিয়োগ করা মানে।
ম্যালকমমিশন

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

100

যদিও অ্যারেলিস্ট ব্যবহারের প্রস্তাব দেওয়ার উত্তরগুলি বেশিরভাগ দৃশ্যে উপলব্ধি করে, আপেক্ষিক পারফরম্যান্সের আসল প্রশ্নের সত্যই উত্তর দেওয়া যায় নি।

অ্যারে দিয়ে আপনি করতে পারেন এমন কয়েকটি জিনিস রয়েছে:

  • এটি তৈরি করুন
  • একটি আইটেম সেট করুন
  • একটি আইটেম পেতে
  • এটি ক্লোন / অনুলিপি করুন

সাধারণ উপসংহার

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

  • একটি তালিকার পুনরায় আকার দেওয়ার ক্রিয়াকলাপগুলি (কল করার সময় list.add(...)) ব্যয়বহুল এবং যখন সম্ভব হয় পর্যাপ্ত পর্যায়ে প্রাথমিক ক্ষমতা সেট করার চেষ্টা করা উচিত (দ্রষ্টব্য যে অ্যারে ব্যবহারের সময় একই সমস্যা দেখা দেয়)
  • আদিমদের সাথে কাজ করার সময় অ্যারেগুলি উল্লেখযোগ্যভাবে দ্রুততর হতে পারে কারণ তারা কাউকে অনেকগুলি বক্সিং / আনবক্সিং রূপান্তর এড়াতে দেয় will
  • একটি অ্যাপ্লিকেশন যা কেবলমাত্র অ্যারেলিস্টে মানগুলি সেট / সেট করে (খুব সাধারণ নয়!) একটি অ্যারেতে স্যুইচ করে 25%-রও বেশি পারফরম্যান্স লাভ দেখতে পারে

বিস্তারিত ফলাফল

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

অ্যারে / অ্যারেলিস্ট ক্রিয়েশন

নিম্নলিখিত বিবৃতিগুলি কার্যকর করে আমি 4 টি পরীক্ষা চালিয়েছি:

  • createArray1: Integer[] array = new Integer[1];
  • createList1: List<Integer> list = new ArrayList<> (1);
  • createArray10000: Integer[] array = new Integer[10000];
  • createList10000: List<Integer> list = new ArrayList<> (10000);

ফলাফল (কল প্রতি ন্যানোসেকেন্ডে, 95% আত্মবিশ্বাস):

a.p.g.a.ArrayVsList.CreateArray1         [10.933, 11.097]
a.p.g.a.ArrayVsList.CreateList1          [10.799, 11.046]
a.p.g.a.ArrayVsList.CreateArray10000    [394.899, 404.034]
a.p.g.a.ArrayVsList.CreateList10000     [396.706, 401.266]

উপসংহার: কোন লক্ষণীয় পার্থক্য

অপারেশন পেতে

আমি নিম্নলিখিত পরীক্ষাগুলি সম্পাদন করে 2 টি পরীক্ষা চালিয়েছি:

  • getList: return list.get(0);
  • getArray: return array[0];

ফলাফল (কল প্রতি ন্যানোসেকেন্ডে, 95% আত্মবিশ্বাস):

a.p.g.a.ArrayVsList.getArray   [2.958, 2.984]
a.p.g.a.ArrayVsList.getList    [3.841, 3.874]

উপসংহার: একটি অ্যারে থেকে পাওয়া একটি অ্যারেলিস্ট থেকে পাওয়ার চেয়ে প্রায় 25% দ্রুত , যদিও পার্থক্যটি কেবল একটি ন্যানোসেকেন্ডের ক্রম অনুসারে।

অপারেশন সেট করুন

আমি নিম্নলিখিত পরীক্ষাগুলি সম্পাদন করে 2 টি পরীক্ষা চালিয়েছি:

  • setlist: list.set(0, value);
  • setArray: array[0] = value;

ফলাফল (প্রতি কল প্রতি ন্যানোসেকেন্ডে):

a.p.g.a.ArrayVsList.setArray   [4.201, 4.236]
a.p.g.a.ArrayVsList.setList    [6.783, 6.877]

উপসংহার: অ্যারেগুলিতে সেট অপারেশন তালিকাগুলির তুলনায় প্রায় 40% দ্রুত , তবে প্রাপ্ত হিসাবে প্রতিটি সেট অপারেশন কয়েক ন্যানো সেকেন্ড নেয় - সুতরাং পার্থক্যটি 1 সেকেন্ডে পৌঁছানোর জন্য, তালিকায় / অ্যারে শত শত আইটেম সেট করতে হবে কয়েক মিলিয়ন বার!

ক্লোন / কপি

অ্যারেলিস্টের অনুলিপি নির্মাণকারীর প্রতিনিধিত্ব করা Arrays.copyOfযাতে পারফরম্যান্সে অ্যারে অনুলিপি (একটি অ্যারের মাধ্যমে অনুলিপি করা clone, Arrays.copyOfবা System.arrayCopy কোনও উপাদান পার্থক্য কর্মক্ষমতা অনুযায়ী তৈরি করে না ) হিসাবে সমান ।


1
চমৎকার বিশ্লেষণ। তবে, আপনার মন্তব্যের প্রসঙ্গে "আদিমদের সাথে কথা বলার সময় অ্যারেগুলি উল্লেখযোগ্যভাবে দ্রুত হতে পারে কারণ তারা একজনকে অনেকগুলি বক্সিং / আনবক্সিং রূপান্তর এড়াতে দেয়", আপনি নিজের পিঠা রাখতে পারেন এবং এটিও খেতে পারেন, আদি-অ্যারে-ব্যাকড লিস্ট সহ বাস্তবায়ন; উদাঃ github.com/scijava/scijava-common/blob/master/src/main/java/org/… । আমি আসলে বেশ অবাক হয়েছি এ জাতীয় জিনিসটি এটি মূল জাভাতে পরিণত করে নি।
ctrueden

2
@ctrueden হ্যাঁ মন্তব্যটি মানক JDK অ্যারেলিস্টে প্রয়োগ করেছে। trove4j একটি বিখ্যাত গ্রন্থাগার যা আদিম তালিকা সমর্থন করে। জাভা 8 বেশ কয়েকটি আদিম-বিশেষায়িত স্ট্রিমগুলির সাথে কিছু উন্নতি এনেছে।
Assylias

আমি জানি না কীভাবে জেএমএইচ বেঞ্চমার্কগুলি কাজ করে তবে তারা কী জেআইটি সংকলনটি ঘটতে পারে তা বিবেচনায় নেয়? জেভিএম আপনার কোডটি সংকলন করার সাথে সাথে জাভা অ্যাপ্লিকেশনটির কার্য সম্পাদন সময়ের সাথে সাথে পরিবর্তিত হতে পারে।
হফম্যান 14

@ হাফম্যান হ্যাঁ - এতে একটি ওয়ার্মআপ পর্ব অন্তর্ভুক্ত রয়েছে যা পরিমাপ থেকে বাদ দেওয়া হয়েছে।
Assylias

97

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

তবে, সর্বদা হিসাবে, অনুকূল করার সময় আপনার সর্বদা এই পদক্ষেপগুলি অনুসরণ করা উচিত:

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

24

আমি অনুমান করছি আসল পোস্টারটি একটি সি ++ / এসটিএল ব্যাকগ্রাউন্ড থেকে আসছে যা কিছু বিভ্রান্তির সৃষ্টি করছে। সি ++ std::listএ দ্বিগুণ সংযুক্ত তালিকা।

জাভাতে [java.util.]Listএকটি বাস্তবায়ন-মুক্ত ইন্টারফেস (সি ++ পদগুলিতে খাঁটি বিমূর্ত শ্রেণি)। Listদ্বিগুণ সংযুক্ত তালিকা হতে পারে - java.util.LinkedListসরবরাহ করা হয়। তবে আপনি যখন নতুন তৈরি করতে চান তখন 100 এর মধ্যে 99 বার List, আপনি java.util.ArrayListপরিবর্তে এটি ব্যবহার করতে চান , এটি সি ++ এর মোটামুটি সমতুল্য std::vector। এ জাতীয় দ্বারা ফিরে সেই হিসাবে অন্যান্য মান বাস্তবায়নের হয় java.util.Collections.emptyList()এবং java.util.Arrays.asList()

পারফরম্যান্সের দৃষ্টিকোণ থেকে একটি ইন্টারফেস এবং একটি অতিরিক্ত অবজেক্টের মধ্য দিয়ে যেতে খুব ছোট হিট হয়, তবে রানটাইম ইনলাইনিংয়ের অর্থ এর খুব কমই এর তাত্পর্য আছে। এছাড়াও মনে রাখবেন যে Stringসাধারণত একটি অবজেক্ট প্লাস অ্যারে হয়। সুতরাং প্রতিটি প্রবেশের জন্য আপনার কাছে সম্ভবত আরও দুটি অবজেক্ট রয়েছে। সি ++ তে std::vector<std::string>, যদিও বিনা পয়েন্টার ছাড়াই মান দ্বারা অনুলিপি করা হচ্ছে, অক্ষর অ্যারেগুলি স্ট্রিংয়ের জন্য একটি অবজেক্ট তৈরি করবে (এবং এগুলি সাধারণত ভাগ করা হবে না)।

যদি এই নির্দিষ্ট কোডটি সত্যই পারফরম্যান্স-সংবেদনশীল হয় তবে আপনি সমস্ত স্ট্রিংয়ের সমস্ত অক্ষরের জন্য একটি একক char[]অ্যারে (বা এমনকি byte[]) তৈরি করতে পারেন এবং তারপরে অফসেটের একটি অ্যারে তৈরি করতে পারেন। আইআইআরসি, জাভ্যাক এভাবেই প্রয়োগ করা হয়।


1
উত্তরের জন্য ধন্যবাদ। তবে না, আমি জাভার ইন্টারফেস তালিকার সাথে সি ++ তালিকাটি বিভ্রান্ত করছি না। আমি প্রশ্নটি এমনভাবে জিজ্ঞাসা করেছি কারণ আমি অ্যারেলিস্ট এবং ভেক্টরের মতো তালিকা বাস্তবায়নের কাঁচা অ্যারের সাথে তুলনা করতে চেয়েছিলাম।
euphoria83

অ্যারেলিস্ট এবং ভেক্টর উভয়ই "সমস্ত ডেটা মেমরির সংলগ্ন অংশে রাখে"।
টম হাটিন -

13

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

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

কিছু কোড:

import java.util.*;

public class ArrayVsArrayList {
    static public void main( String[] args ) {

        String[] array = new String[300];
        ArrayList<String> list = new ArrayList<String>(300);

        for (int i=0; i<300; ++i) {
            if (Math.random() > 0.5) {
                array[i] = "abc";
            } else {
                array[i] = "xyz";
            }

            list.add( array[i] );
        }

        int iterations = 100000000;
        long start_ms;
        int sum;

        start_ms = System.currentTimeMillis();
        sum = 0;

        for (int i=0; i<iterations; ++i) {
          for (int j=0; j<300; ++j) sum += array[j].length();
        }

        System.out.println( (System.currentTimeMillis() - start_ms) + " ms (array)" );
        // Prints ~13,500 ms on my system

        start_ms = System.currentTimeMillis();
        sum = 0;

        for (int i=0; i<iterations; ++i) {
          for (int j=0; j<300; ++j) sum += list.get(j).length();
        }

        System.out.println( (System.currentTimeMillis() - start_ms) + " ms (ArrayList)" );
        // Prints ~20,800 ms on my system - about 1.5x slower than direct array access
    }
}

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

4
এই মাইক্রো বেঞ্চমার্কের ত্রুটি রয়েছে (কোনও প্রস্তুতি নেই, আলাদা পদ্ধতিতে কাজ করা হবে না তাই অ্যারেলিস্ট অংশটি জেআইটি ইত্যাদির দ্বারা কখনই অনুকূলিত হয় না)
অ্যাসিরিয়াস

আমি অ্যাসিলিয়াসের সাথে একমত এই মানদণ্ডের ফলাফলগুলিতে বিশ্বাস করা উচিত নয়।
স্টিফেন সি

@ স্টেফেনসি আমি একটি সঠিক মাইক্রো বেঞ্চমার্ক যুক্ত করেছি (এটি দেখায় যে অপারেশনগুলি তুলনামূলক হয়)।
Assylias

11

ভাল প্রথমে এটি স্পষ্ট করে বলা আপনার ক্লাসিক্যাল কম্প সায়েন্স ডেটা স্ট্রাকচার অর্থে "তালিকা" মানে (অর্থাত একটি লিঙ্কযুক্ত তালিকা) বা আপনি জাভা.ইটিল.লিস্ট বলতে চান? আপনি যদি java.util.List বলতে চান তবে এটি একটি ইন্টারফেস। আপনি যদি অ্যারে ব্যবহার করতে চান তবে অ্যারেলিস্ট প্রয়োগটি ব্যবহার করুন এবং আপনি অ্যারের মতো আচরণ এবং শব্দার্থবিজ্ঞান পাবেন get সমস্যা সমাধান.

যদি আপনি কোনও অ্যারে বনাম কোনও লিঙ্কযুক্ত তালিকার অর্থ বোঝায় তবে এটি কিছুটা আলাদা যুক্তি যার জন্য আমরা বিগ ও-তে ফিরে যাই (এটি যদি অপরিচিত শব্দ হয় তবে এখানে একটি সরল ইংরেজী ব্যাখ্যা দেওয়া আছে)

এরে;

  • এলোমেলো অ্যাক্সেস: ও (1);
  • Sertোকান: ও (এন);
  • মুছুন: ও (এন)।

যোজিত তালিকা:

  • এলোমেলো অ্যাক্সেস: ও (এন);
  • Sertোকান: ও (1);
  • মুছুন: ও (1)

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

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


আমি java.util.List ইন্টারফেস বলতে চাইছি
euphoria83

1
লিঙ্কযুক্ত তালিকার এলোমেলো অ্যাক্সেস ও (এন) আমার কাছে বড় ব্যাপার বলে মনে হচ্ছে।
জর্জন

11

অ্যারেলিস্টগুলি অ্যারের সাথে তুলনা করার জন্য আমি একটি সামান্য বেঞ্চমার্ক লিখেছি। আমার পুরানো-ইশ ল্যাপটপে, 5000 বারের উপাদান অ্যারেলিস্টের মাধ্যমে 1000 বার অতিক্রম করার সময়টি সমমানের অ্যারে কোডের চেয়ে প্রায় 10 মিলিসেকেন্ড স্লো ছিল।

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

বিশেষ দ্রষ্টব্য আমি করেনি যে বিজ্ঞপ্তি ব্যবহার for String s: stringsListঅ্যাক্সেস করতে তালিকার জন্য লুপ একটি পুরানো ধাঁচের ব্যবহার না করে প্রায় 50% ধীর ছিল। ফিগার যান ... এখানে আমি দুটি কার্য সম্পাদন করেছি; অ্যারে এবং তালিকাটি 5000 এলোমেলো (বিভিন্ন) স্ট্রিং দিয়ে ভরাট হয়েছিল।

private static void readArray(String[] strings) {
    long totalchars = 0;
    for (int j = 0; j < ITERATIONS; j++) {
        totalchars = 0;
        for (int i = 0; i < strings.length; i++) {
            totalchars += strings[i].length();

        }
    }
}

private static void readArrayList(List<String> stringsList) {
    long totalchars = 0;
    for (int j = 0; j < ITERATIONS; j++) {
        totalchars = 0;
        for (int i = 0; i < stringsList.size(); i++) {
            totalchars += stringsList.get(i).length();
        }
    }
}

@ ক্রিস মে: দুর্দান্ত কাজ! উভয়ের আসল সময়গুলি কী? আপনি যে স্ট্রিং ব্যবহার করছিলেন সেটির আকার বলতে পারেন? এছাড়াও, 'স্ট্রিংস: স্ট্রিংলিস্ট' এর ব্যবহার যেহেতু এটি আরও বেশি সময় নিয়েছে, সাধারণভাবে জাভাতে উচ্চতর বিমূর্ততা ব্যবহার করা এটিই আমার প্রাথমিক ভয়।
euphoria83

এই mcirobenchmark এর জন্য স্ট্রিংগুলি কত দিন সত্য তা বিবেচ্য নয়। কোনও গিসি নেই, এবং এটি char[]স্পর্শও করা হয়নি (এটি সি নয়)।
টম হাটিন -

আমার জন্য সাধারণ সময়গুলি অ্যারের সংস্করণের জন্য 25 মিলিয়ন ডলার, অ্যারেলিস্ট সংস্করণের জন্য 35 ডলার। স্ট্রিংগুলি 15-20 অক্ষর দীর্ঘ ছিল। টম যেমন বলেছেন, স্ট্রিংয়ের আকারটি খুব বেশি পার্থক্য করে না, a 100-চর স্ট্রিংয়ের সময়গুলি একই রকম ছিল।
ক্রিস মে

3
আপনি কীভাবে পরিমাপ করলেন? জাভা মাইক্রো বেনমার্কগুলিতে নিষ্পাপ পরিমাপ তথ্য সাধারণত তথ্যের চেয়ে বেশি ভুল তথ্য উত্পন্ন করে। উপরের বিবৃতি থেকে সাবধান।
jmg

6

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


5
তালিকাগুলি কেবল স্ট্রিংগুলিতে রেফারেন্স সঞ্চয় করে।
পিটার btibraný

6

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

উদাহরণস্বরূপ, যদি স্ট্রিংগুলি ছিল

intern
international
internationalize
internet
internets

ট্রাই সংরক্ষণ করবে:

intern
 -> \0
 international
 -> \0
 -> ize\0
 net
 ->\0
 ->s\0

স্ট্রিংয়ের জন্য স্ট্রিংয়ের জন্য 57 টি অক্ষর (নাল টার্মিনেটর সহ '\ 0') প্রয়োজন হয়, তারপরে স্ট্রিং অবজেক্টের আকার যাই হোক না কেন। (সত্য বলতে গেলে, আমাদের সম্ভবত সমস্ত আকার 16 এর গুণক পর্যন্ত হওয়া উচিত, তবে ...) এটিকে মোটামুটিভাবে 57 + 5 = 62 বাইট বলুন।

ট্রাইয়ের জন্য স্টোরেজের জন্য 29 টি (নাল টার্মিনেটর সহ '\ 0') প্রয়োজন হয়, ত্রি ট্র্যাক নোডের আকারের, যা অ্যারেতে রেফ এবং শিশু ট্রাই নোডের একটি তালিকা।

এই উদাহরণস্বরূপ, সম্ভবত এটি একই সম্পর্কে আসে; আপনার সাধারণ উপসর্গগুলি যতক্ষণ না হাজার সহস্র, এটি সম্ভবত কম আসে।

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

তবে আপনি যদি কেবলমাত্র কয়েকটি ব্যবহার করছেন - বলুন, অভিধানে জিনিসগুলি অনুসন্ধান করতে - ট্রাই আপনাকে অনেক জায়গা বাঁচাতে পারে। হ্যাশসেটে সেগুলি সঞ্চয় করার চেয়ে অবশ্যই কম স্থান।

আপনি বলছেন যে আপনি এগুলি "সিরিয়ালি" অ্যাক্সেস করছেন - যদি এর অর্থ ক্রমানুসারে বর্ণমালা অনুসারে হয় তবে ট্রি আপনি স্পষ্টতই বর্ণমালার অর্ডার প্রদান করেন, যদি আপনি এটির গভীরতা-প্রথমটি পুনরাবৃত্তি করেন।


1
একটি লাইব্রেরির মতো ত্রয়ী বা আমি কীভাবে এটি তৈরি করব?
euphoria83

একটি টেরি কেবলমাত্র টোকেনাইজড স্ট্রিংয়ের ক্ষেত্রে কার্যকর হবে, যদি না কেউ চলমান পাঠ্যকে স্ট্রিং হিসাবে সংরক্ষণ করে।
এমএন

5

হালনাগাদ:

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

তবুও প্রথম 1-2 পাসে সহজ অ্যারে 2-3 গুণ দ্রুত হয়।

মূল পোস্ট:

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

import java.util.List;
import java.util.Arrays;

public class IterationTest {

    private static final long MAX_ITERATIONS = 1000000000;

    public static void main(String [] args) {

        Integer [] array = {1, 5, 3, 5};
        List<Integer> list = Arrays.asList(array);

        long start = System.currentTimeMillis();
        int test_sum = 0;
        for (int i = 0; i < MAX_ITERATIONS; ++i) {
//            for (int e : array) {
            for (int e : list) {
                test_sum += e;
            }
        }
        long stop = System.currentTimeMillis();

        long ms = (stop - start);
        System.out.println("Time: " + ms);
    }
}

এবং এখানে উত্তর:

অ্যারের উপর ভিত্তি করে (লাইন 16 সক্রিয় রয়েছে):

Time: 7064

তালিকার উপর ভিত্তি করে (লাইন 17 সক্রিয় রয়েছে):

Time: 20950

'দ্রুত' নিয়ে আর কোনও মন্তব্য? এটা বেশ বোঝা যাচ্ছে। প্রশ্নটি যখন তালিকার নমনীয়তার চেয়ে প্রায় 3 বার দ্রুত আপনার জন্য ভাল। তবে এটি আরেকটি প্রশ্ন। উপায় দ্বারা আমি এটি নিজে তৈরির ভিত্তিতেও পরীক্ষা করেছিলাম ArrayList। প্রায় একই ফলাফল।


2
3বার দ্রুত সত্য, কিন্তু তুচ্ছ। 14msদীর্ঘ সময় নয়
0x6C38

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

5

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

এটি প্রকৃত সাধারণ পারফরম্যান্স চেক।
সুতরাং, ফলাফলটি মেশিনের কার্য সম্পাদনের উপর নির্ভর করবে।

এর জন্য ব্যবহৃত সোর্স কোডটি নীচে:

import java.util.Iterator;
import java.util.LinkedList;

public class Array_vs_LinkedList {

    private final static int MAX_SIZE = 40000000;

    public static void main(String[] args) {

        LinkedList lList = new LinkedList(); 

        /* insertion performance check */

        long startTime = System.currentTimeMillis();

        for (int i=0; i<MAX_SIZE; i++) {
            lList.add(i);
        }

        long stopTime = System.currentTimeMillis();
        long elapsedTime = stopTime - startTime;
        System.out.println("[Insert]LinkedList insert operation with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");

        int[] arr = new int[MAX_SIZE];

        startTime = System.currentTimeMillis();
        for(int i=0; i<MAX_SIZE; i++){
            arr[i] = i; 
        }

        stopTime = System.currentTimeMillis();
        elapsedTime = stopTime - startTime;
        System.out.println("[Insert]Array Insert operation with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");


        /* iteration performance check */

        startTime = System.currentTimeMillis();

        Iterator itr = lList.iterator();

        while(itr.hasNext()) {
            itr.next();
            // System.out.println("Linked list running : " + itr.next());
        }

        stopTime = System.currentTimeMillis();
        elapsedTime = stopTime - startTime;
        System.out.println("[Loop]LinkedList iteration with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");


        startTime = System.currentTimeMillis();

        int t = 0;
        for (int i=0; i < MAX_SIZE; i++) {
            t = arr[i];
            // System.out.println("array running : " + i);
        }

        stopTime = System.currentTimeMillis();
        elapsedTime = stopTime - startTime;
        System.out.println("[Loop]Array iteration with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");
    }
}

পারফরম্যান্স ফলাফল নীচে:

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



4

মনে রাখবেন যে একটি অ্যারেলিস্ট একটি অ্যারে encapsulates, তাই একটি আদিম অ্যারে ব্যবহার করার তুলনায় সামান্য পার্থক্য আছে (জাভাতে একটি তালিকা কাজ করা খুব সহজ যে ব্যতীত)।

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


4

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

  1. যদি স্ট্রিংয়ের সংখ্যা প্রায় স্থির থাকে তবে একটি অ্যারে (বা অ্যারেলিস্ট) ব্যবহার করুন। তবে সংখ্যাটি যদি খুব বেশি পরিবর্তিত হয় তবে আপনি আরও ভালভাবে লিংকডলিস্টটি ব্যবহার করতে পারবেন।
  2. মাঝখানে উপাদান যুক্ত করতে বা মুছতে যদি প্রয়োজন (বা হবে) হয় তবে অবশ্যই আপনাকে লিঙ্কডলিস্টটি ব্যবহার করতে হবে।

4

অ্যারেতে তালিকা ব্যবহারের পারফরম্যান্স প্রভাবের জন্য আমি আরও ভাল অনুভূতি পেতে এখানে এসেছি। আমার দৃশ্যের জন্য আমাকে কোডটি এখানে মানিয়ে নিতে হয়েছিল: বেশিরভাগ গেটার ব্যবহার করে অ্যারে / 1000 ডলার ইনটগুলির তালিকা, যার অর্থ অ্যারে [জে] বনাম তালিকা.জেট (জে)

এটি সম্পর্কে অবৈজ্ঞানিক হতে 7 টির সেরাটি গ্রহণ করা (প্রথম কয়েকটি যেখানে 2.5x ধীর গতির) এটি পেয়েছি:

array Integer[] best 643ms iterator
ArrayList<Integer> best 1014ms iterator

array Integer[] best 635ms getter
ArrayList<Integer> best 891ms getter (strange though)

- সুতরাং, অ্যারের সাথে প্রায় 30% দ্রুত

এখন পোস্ট করার দ্বিতীয় কারণ হ'ল আপনি নেস্টেড লুপগুলি সহ গণিত / ম্যাট্রিক্স / সিমুলেশন / অপ্টিমাইজেশন কোড করেন তবে কেউই প্রভাবটির কথা উল্লেখ করে না ।

বলুন আপনার কাছে তিনটি নেস্টেড লেভেল রয়েছে এবং আপনি 8 বারের পারফরম্যান্স হিটটি দেখছেন তার অভ্যন্তরীণ লুপ দ্বিগুণ twice একদিনে চলতে পারে এমন এক জিনিস এখন এক সপ্তাহ সময় নেয়।

* সম্পাদনা এখানে বেশ চমকে গেলেন, কিকের জন্য আমি পূর্ণসংখ্যা [1000] এর চেয়ে ইন্ট [1000] ঘোষণা করার চেষ্টা করেছি

array int[] best 299ms iterator
array int[] best 296ms getter

পূর্ণসংখ্যার ব্যবহার [] বনাম ইন্ট [] দ্বিগুণ পারফরম্যান্স হিটকে উপস্থাপন করে, পুনরাবৃত্তির সাথে তালিকাআররেটি int এর চেয়ে 3x ধীর []। সত্যিই ভেবেছিল জাওয়ার তালিকা বাস্তবায়ন দেশীয় অ্যারেগুলির মতো ...

রেফারেন্সের জন্য কোড (একাধিকবার কল করুন):

    public static void testArray()
    {
        final long MAX_ITERATIONS = 1000000;
        final int MAX_LENGTH = 1000;

        Random r = new Random();

        //Integer[] array = new Integer[MAX_LENGTH];
        int[] array = new int[MAX_LENGTH];

        List<Integer> list = new ArrayList<Integer>()
        {{
            for (int i = 0; i < MAX_LENGTH; ++i)
            {
                int val = r.nextInt();
                add(val);
                array[i] = val;
            }
        }};

        long start = System.currentTimeMillis();
        int test_sum = 0;
        for (int i = 0; i < MAX_ITERATIONS; ++i)
        {
//          for (int e : array)
//          for (int e : list)          
            for (int j = 0; j < MAX_LENGTH; ++j)
            {
                int e = array[j];
//              int e = list.get(j);
                test_sum += e;
            }
        }

        long stop = System.currentTimeMillis();

        long ms = (stop - start);
        System.out.println("Time: " + ms);
    }

3

আপনি যদি ডেটাটি কত বড় তা আগেই জানেন তবে একটি অ্যারে আরও দ্রুত হবে।

একটি তালিকা আরও নমনীয়। আপনি একটি অ্যারেলিস্ট ব্যবহার করতে পারেন যা একটি অ্যারের দ্বারা ব্যাকযুক্ত।


অ্যারেলিস্টে একটি নিশ্চিত ক্যাপাসিটি () পদ্ধতি রয়েছে যা ব্যাকিং অ্যারেটিকে নির্দিষ্ট আকারে পূর্বনির্ধারণ করে।
জেস্পের ই

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

3

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

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

অতএব আপনি http://java.dzone.com/articles/gaplist-%E2%80%93- আলোকসজ্জা-তালিকা- তালিকাটি দেখতে চান যা গ্যাপলিস্টটি প্রবর্তন করে। এই নতুন তালিকার প্রয়োগটি অ্যারেলিস্ট এবং লিংকডলিস্ট উভয়ের শক্তিকে একত্রিত করে যার ফলে প্রায় সমস্ত ক্রিয়াকলাপের জন্য খুব ভাল পারফরম্যান্স হয়।


2

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

অবশ্যই, jvm বাস্তবায়নের পক্ষে এই পরিস্থিতির জন্য একটি বিশেষ কেস থাকা সম্ভব, যার ক্ষেত্রে পারফরম্যান্স একই হবে the


2

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


2

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

ওরাকল জাভা সেরা অনুশীলন দেখুন: http://docs.oracle.com/cd/A97688_16/generic.903/bp/java.htm#1007056

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


আপনি যে ডকুমেন্টেশনটির সাথে লিঙ্ক করেছেন সেটি 10 ​​বছরেরও বেশি পুরানো, যা জাভা 1.3 এর জন্য প্রযোজ্য। তার পর থেকে মুখ্য পারফরম্যান্সের উন্নতি হয়েছে ...
Assylias

@ এ্যাসিয়ালিরা উপরের উত্তরগুলি দেখুন, তাদের মধ্যে পারফরম্যান্স টেস্ট রয়েছে, যা বলছে যে অ্যারেগুলি আরও দ্রুত
নিক

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

2

উত্তরের কোনওটিতেই আমি আগ্রহী এমন তথ্য ছিল না - একই অ্যারের পুনরাবৃত্তি স্ক্যান বহুবার। এর জন্য জেএমএইচ পরীক্ষা তৈরি করতে হয়েছিল।

ফলাফল (জাভা 1.8.0_66 x32, পুনরাবৃত্তি প্লে অ্যারে অ্যারেলিস্টের চেয়ে কমপক্ষে 5 গুণ দ্রুত):

Benchmark                    Mode  Cnt   Score   Error  Units
MyBenchmark.testArrayForGet  avgt   10   8.121 ? 0.233  ms/op
MyBenchmark.testListForGet   avgt   10  37.416 ? 0.094  ms/op
MyBenchmark.testListForEach  avgt   10  75.674 ? 1.897  ms/op

পরীক্ষা

package my.jmh.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@State(Scope.Benchmark)
@Fork(1)
@Warmup(iterations = 5, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 10)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class MyBenchmark {

    public final static int ARR_SIZE = 100;
    public final static int ITER_COUNT = 100000;

    String arr[] = new String[ARR_SIZE];
    List<String> list = new ArrayList<>(ARR_SIZE);

    public MyBenchmark() {
        for( int i = 0; i < ARR_SIZE; i++ ) {
            list.add(null);
        }
    }

    @Benchmark
    public void testListForEach() {
        int count = 0;
        for( int i = 0; i < ITER_COUNT; i++ ) {
            for( String str : list ) {
                if( str != null )
                    count++;
            }
        }
        if( count > 0 )
            System.out.print(count);
    }

    @Benchmark
    public void testListForGet() {
        int count = 0;
        for( int i = 0; i < ITER_COUNT; i++ ) {
            for( int j = 0; j < ARR_SIZE; j++ ) {
                if( list.get(j) != null )
                    count++;
            }
        }
        if( count > 0 )
            System.out.print(count);
    }

    @Benchmark
    public void testArrayForGet() {
        int count = 0;
        for( int i = 0; i < ITER_COUNT; i++ ) {
            for( int j = 0; j < ARR_SIZE; j++ ) {
                if( arr[j] != null )
                    count++;
            }
        }
        if( count > 0 )
            System.out.print(count);
    }

}

2

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


সর্বাধিক -৪-বিট বাস্তবায়নে 8 বাইট।
টম হাটিন -

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

1

যথাযথ বেঞ্চমার্কিং না করে অনুকূলকরণের ফাঁদে যাবেন না। অন্যরা যেমন কোনও অনুমান করার আগে একজন প্রোফাইলার ব্যবহার করার পরামর্শ দিয়েছে।

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

মেমরির খরচ সম্পর্কে। আপনি কিছু জিনিস মিশ্রিত করা হয় বলে মনে হচ্ছে। আপনার কাছে থাকা ডেটার ধরণের জন্য একটি অ্যারে আপনাকে কেবল অবিচ্ছিন্ন মেমরি দেয়। ভুলে যাবেন না যে জাভাতে একটি নির্দিষ্ট ডেটা রয়েছে: বুলিয়ান, চর, ইনট, লং, ফ্লোট এবং অবজেক্ট (এটিতে সমস্ত অবজেক্ট এমনকি একটি অ্যারেও একটি অবজেক্ট থাকে) include এর অর্থ হ'ল আপনি যদি স্ট্রিং স্ট্রিংগুলির একটি অ্যারে [1000] বা মাইবজেক্ট মাইঅবজেক্টস [1000] ঘোষণা করেন তবে আপনি কেবলমাত্র 1000 টি মেমরি বাক্স পাবেন যাতে অবজেক্টগুলির অবস্থান (রেফারেন্স বা পয়েন্টার) সঞ্চয় করতে পারে। আপনি কোনও 1000 মেমরি বাক্স পাবেন না যা বড় আকারের বস্তুর আকারের জন্য উপযুক্ত fit ভুলে যাবেন না যে আপনার অবজেক্টগুলি প্রথম "নতুন" দিয়ে তৈরি হয়েছিল। এটি যখন মেমরি বরাদ্দ করা হয় এবং পরে একটি রেফারেন্স (তাদের মেমরি ঠিকানা) অ্যারেতে সংরক্ষণ করা হয়। কেবলমাত্র এটির রেফারেন্সে অবজেক্টটি অ্যারে অনুলিপি করা হয় না।


1

আমি মনে করি না এটি স্ট্রিংয়ের ক্ষেত্রে সত্যিকারের পার্থক্য তৈরি করে। স্ট্রিংগুলির একটি অ্যারেতে যা সামঞ্জস্যপূর্ণ তা হ'ল স্ট্রিংয়ের উল্লেখ, স্ট্রিংগুলি এলোমেলো স্থানে স্মৃতিতে সংরক্ষণ করা হয়।

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



1

এখানে প্রদত্ত প্রচুর মাইক্রোবেনমার্কগুলি অ্যারে / অ্যারেলিস্ট পঠনের মতো জিনিসের জন্য কয়েকটি ন্যানোসেকেন্ডের সংখ্যা পেয়েছে। সবকিছু আপনার L1 ক্যাশে থাকলে এটি বেশ যুক্তিসঙ্গত।

একটি উচ্চ স্তরের ক্যাশে বা প্রধান মেমরি অ্যাক্সেসে 10nS-100nS এর মতো কোনও কিছুর দৈর্ঘ্যের বারের ক্রম থাকতে পারে, L1 ক্যাশের জন্য আরও 1nS এর মতো বনাম। একটি অ্যারেলিস্ট অ্যাক্সেসের একটি অতিরিক্ত মেমরি ইন্ডিয়ারেশন রয়েছে এবং আপনার কোডটি অ্যাক্সেসের মধ্যে কী করছে তার উপর নির্ভর করে আপনি সত্যিকারের অ্যাপ্লিকেশনটিতে প্রায় কোনও সময়ই এই খরচটি কিছুটা দিতে পারেন। এবং অবশ্যই, আপনার যদি অনেক ছোট অ্যারেলিস্ট থাকে তবে এটি আপনার মেমরির ব্যবহারে যুক্ত হতে পারে এবং এটির বেশি সম্ভাবনা রয়েছে যা আপনার ক্যাশে মিস করেছে।

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

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


0

এটি আপনাকে কীভাবে অ্যাক্সেস করতে হবে তার উপর নির্ভর করে।

সংরক্ষণ করার পরে, আপনি যদি প্রাথমিকভাবে সন্ধান অপারেশন করতে চান, খুব কম বা কোনও সন্নিবেশ / মোছা না করে, তারপরে অ্যারেতে যান (যেমন অনুসন্ধানে ও (1) এ অ্যারে করা হয়, তবে যোগ / মুছার জন্য উপাদানগুলির পুনঃক্রমের প্রয়োজন হতে পারে) ।

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


0

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

অ্যারে অ্যারের চেয়ে দ্রুততর কারণ অ্যারেলিস্ট অভ্যন্তরীণভাবে অ্যারে ব্যবহার করে। যদি আমরা সরাসরি অ্যারেতে উপাদান যুক্ত করতে পারি এবং অপ্রত্যক্ষভাবে অ্যারেতে অ্যারেরে উপাদান যুক্ত করতে পারি অ্যারেলিস্টের মাধ্যমে সর্বদা প্রত্যক্ষ প্রক্রিয়া অপ্রত্যক্ষভাবে ব্যবস্থার চেয়ে দ্রুত হয়।

অ্যারেলিস্ট ক্লাসে দুটি ওভারলোডেড অ্যাড () পদ্ধতি রয়েছে:
add(Object) : তালিকার শেষে অবজেক্ট যুক্ত করে adds
add(int index , Object ) : তালিকার নির্দিষ্ট অবস্থানে নির্দিষ্ট বস্তু সন্নিবেশ করান।

অ্যারেলিস্টের আকার কীভাবে গতিশীলভাবে বৃদ্ধি পায়?

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

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

জাভা 6 অবধি

int newCapacity = (oldCapacity * 3)/2 + 1;

(আপডেট) জাভা 7 থেকে

 int newCapacity = oldCapacity + (oldCapacity >> 1);

এছাড়াও, পুরানো অ্যারে থেকে ডেটা নতুন অ্যারেতে অনুলিপি করা হয়।

অ্যারেলিস্টে ওভারহেড পদ্ধতি থাকার কারণে অ্যারের চেয়ে দ্রুততর হয় ArrayList


0

অ্যারে - যখন ফলাফলগুলি দ্রুত আনতে হয় তখন তা সর্বদা ভাল

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

তবে সর্বদা মনে রাখবেন যে ডাটা সঞ্চিত যখন অ্যারেতে সূচক অবস্থানটি জানা থাকে তখন তথ্য আনতে দ্রুত হবে।

এটি অ্যারে বাছাই করে ভাল অর্জন করা যেতে পারে। অতএব এটি ডেটা আনার সময় বাড়ায় (যেমন; ডেটা সংরক্ষণ করে + তথ্য বাছাই + তথ্য যেখানে পাওয়া যায় তার অবস্থান অনুসন্ধান করুন)। সুতরাং এটি অ্যারে থেকে ডেটা আনতে অতিরিক্ত বিলম্বিতা বাড়ায় এমনকি তারা তাড়াতাড়ি ডেটা আনার ক্ষেত্রে ভাল হতে পারে।

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

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

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