একটি LinkedList দ্রুত হবে? আমার কি 'প্রত্যেকটির জন্য' একটি 'ইটারেটর' দিয়ে অদলবদল করা উচিত? এই 'অ্যারেলিস্ট' কি একটি 'অ্যারে' হওয়া উচিত? এই নিবন্ধটি একটি অপ্টিমাইজেশানের প্রতিক্রিয়া হিসাবে এসেছিল এতটা নৃশংস এটি স্থায়ীভাবে নিজেকে আমার স্মৃতিতে খোদাই করেছে।
জাভাতে যাওয়ার আগে এবং হস্তক্ষেপ মোকাবেলা করার উপায়গুলি, হয় আবর্জনা সংগ্রহকারী থেকে বা প্রসঙ্গ পরিবর্তন থেকে, আসুন প্রথমে আপনার ভবিষ্যতের নিজের জন্য কোড লেখার মৌলিক বিষয়গুলি দেখে নেওয়া যাক।
অকাল অপ্টিমাইজেশান সমস্ত মন্দের মূল।
আপনি আগে এটা শুনেছেন; অকাল অপ্টিমাইজেশান হল সমস্ত মন্দের মূল। ভাল, কখনও কখনও. সফ্টওয়্যার লেখার সময়, আমি এই বিষয়ে দৃঢ় বিশ্বাসী:
যতটা সম্ভব বর্ণনামূলক ; আপনার উদ্দেশ্য বর্ণনা করার চেষ্টা করা উচিত যেন আপনি একটি গল্প লিখছেন।
যতটা সম্ভব সর্বোত্তম ; যার অর্থ হল আপনার ভাষার মৌলিক বিষয়গুলি জানা উচিত এবং সে অনুযায়ী প্রয়োগ করা উচিত।
আপনার কোড অভিপ্রায় কথা বলা উচিত, এবং এটি অনেক আপনি পদ্ধতি এবং ভেরিয়েবলের নামকরণের সাথে সম্পর্কিত।
int[10] array1; // bad int[10] numItems; // better int[10] backPackItems; // great
শুধু পরিবর্তনশীল নাম দ্বারা, আপনি ইতিমধ্যে কার্যকারিতা অনুমান করতে পারেন.
যদিও numItems
বিমূর্ত, backPackItems
আপনাকে প্রত্যাশিত আচরণ সম্পর্কে অনেক কিছু বলে।
অথবা বলুন আপনার এই পদ্ধতি আছে:
List<Countries> visitedCountries() { if(noCountryVisitedYet) return new ArrayList<>(0); } // (...) return listOfVisitedCountries; }
যতদূর কোড যায়, এটি কমবেশি ঠিক দেখায়।
আমরা কি আরও ভাল করতে পারি? আমরা অবশ্যই পারি!
List<Countries> visitedCountries() { if(noCountryVisitedYet) return Collections.emptyList(); } // (...) return listOfVisitedCountries; }
Collections.emptyList()
পড়া new ArrayList<>(0);
কল্পনা করুন যে আপনি প্রথমবার উপরের কোডটি পড়ছেন এবং গার্ড ক্লজটিতে হোঁচট খাচ্ছেন যা চেক করে যে ব্যবহারকারী আসলেই দেশগুলি পরিদর্শন করেছেন কিনা। এছাড়াও, কল্পনা করুন যে এটি একটি দীর্ঘ শ্রেণীতে সমাহিত হয়েছে, Collections.emptyList()
পড়া অবশ্যই new ArrayList<>(0)
এর চেয়ে বেশি বর্ণনামূলক, আপনি নিশ্চিত করছেন যে এটি অপরিবর্তনীয় তা নিশ্চিত করে ক্লায়েন্ট কোড এটি সংশোধন করতে পারে না।
আপনার ভাষা জানুন, এবং সেই অনুযায়ী এটি ব্যবহার করুন। আপনার যদি একটি double
প্রয়োজন হয় তবে এটিকে Double
অবজেক্টে মোড়ানোর দরকার নেই। যদি আপনার আসলে একটি Array
প্রয়োজন হয় তবে একটি List
ব্যবহার করার ক্ষেত্রেও একই কথা যায়।
জেনে রাখুন যে আপনি যদি থ্রেডগুলির মধ্যে স্থিতি ভাগ করে থাকেন তবে আপনার StringBuilder
বা StringBuffer
ব্যবহার করে স্ট্রিংগুলিকে সংযুক্ত করা উচিত:
// don't do this String votesByCounty = ""; for (County county : counties) { votesByCounty += county.toString(); } // do this instead StringBuilder votesByCounty = new StringBuilder(); for (County county : counties) { votesByCounty.append(county.toString()); }
আপনার ডাটাবেস কিভাবে সূচক করতে হয় তা জানুন। সেই অনুযায়ী প্রতিবন্ধকতা এবং ক্যাশে অনুমান করুন। উপরের সবগুলোই অপ্টিমাইজেশান। এগুলি হল এমন ধরনের অপ্টিমাইজেশন যেগুলি সম্পর্কে আপনার সচেতন হওয়া উচিত এবং প্রথম নাগরিক হিসাবে প্রয়োগ করা উচিত৷
আমি কয়েক বছর আগে পড়া একটি হ্যাক সম্পর্কে কখনও ভুলব না। সত্যই বলা যায়, লেখক দ্রুত পিছিয়ে গেলেন, কিন্তু এটি দেখায় যে কীভাবে অনেক মন্দ ভালো উদ্দেশ্য থেকে উদ্বুদ্ধ হতে পারে।
// do not do this, ever! int i = 0; while (i<10000000) { // business logic if (i % 3000 == 0) { //prevent long gc try { Thread.sleep(0); } catch (Ignored e) { } } }
জাহান্নাম থেকে আবর্জনা সংগ্রহকারী হ্যাক!
আপনি মূল নিবন্ধে কেন এবং কীভাবে উপরের কোডটি কাজ করে সে সম্পর্কে আরও পড়তে পারেন এবং যখন শোষণটি অবশ্যই আকর্ষণীয়, এটি সেই জিনিসগুলির মধ্যে একটি যা আপনার কখনই করা উচিত নয়।
Thread.sleep(0)
এই ব্লকের কোন উদ্দেশ্য নেই
শুধুমাত্র একটু বেশি জড়িত কিছু জালিয়াতি শুরু করুন যদি, ভাষা প্রদান করে সমস্ত ডিফল্ট অপ্টিমাইজেশানগুলি দিয়ে লেখার পরে, আপনি একটি বাধার সম্মুখীন হন৷ কিন্তু উপরোক্ত মত কল্পকাহিনী থেকে দূরে বাহা.
যদি সব শেষ হয়ে যায়, আবর্জনা সংগ্রাহক এখনও সেই অংশ যা প্রতিরোধের প্রস্তাব দেয়, এই কিছু জিনিস যা আপনি চেষ্টা করতে পারেন:
যদি আপনার পরিষেবা এতটাই লেটেন্সি-সংবেদনশীল হয় যে আপনি GC-এর জন্য অনুমতি দিতে না পারেন, তাহলে "Epsilon GC" দিয়ে চালান এবং GC সম্পূর্ণভাবে এড়িয়ে যান ৷
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
আপনি একটি OOM ব্যতিক্রম না পাওয়া পর্যন্ত এটি স্পষ্টতই আপনার স্মৃতিশক্তি বৃদ্ধি করবে, তাই হয় এটি একটি স্বল্পস্থায়ী দৃশ্য অথবা আপনার প্রোগ্রামটি বস্তু তৈরি না করার জন্য অপ্টিমাইজ করা হয়েছে
যদি আপনার পরিষেবা কিছুটা লেটেন্সি সংবেদনশীল হয়, তবে অনুমোদিত সহনশীলতা কিছুটা ছাড়ের অনুমতি দেয় , GC1 চালান এবং এটিকে কিছু খাওয়ান যেমন -XX:MaxGCPauseTimeMillis=100
(ডিফল্ট 250ms)
যদি সমস্যাটি বহিরাগত লাইব্রেরি থেকে উদ্বুদ্ধ হয় , বলুন তাদের মধ্যে একটিকে System.gc()
বা Runtime.getRuntime().gc()
বলা হয় যা স্টপ-দ্য-ওয়ার্ল্ড আবর্জনা সংগ্রহকারী, আপনি -XX:+DisableExplicitGC
দিয়ে চালানোর মাধ্যমে আপত্তিকর আচরণকে ওভাররাইড করতে পারেন। -XX:+DisableExplicitGC
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
। আপনি এই JDK 21 GC বেঞ্চমার্কটিও পরীক্ষা করতে চাইতে পারেন।
সংস্করণ শুরু | সংস্করণ শেষ | ডিফল্ট জিসি |
---|---|---|
জাভা ঘ | জাভা 4 | সিরিয়াল আবর্জনা সংগ্রাহক |
জাভা 5 | জাভা 8 | সমান্তরাল আবর্জনা সংগ্রহকারী |
জাভা 9 | চলমান | জি 1 আবর্জনা সংগ্রাহক |
দ্রষ্টব্য 1: জাভা 15 থেকে, ZGC
উত্পাদন-প্রস্তুত , কিন্তু আপনাকে এখনও স্পষ্টভাবে এটি -XX:+UseZGC
দিয়ে সক্রিয় করতে হবে।
দ্রষ্টব্য 2: VM মেশিনগুলিকে সার্ভার-শ্রেণী হিসাবে বিবেচনা করে যদি VM দুটির বেশি প্রসেসর সনাক্ত করে এবং 1792 MB এর সমান বড় বা সমান একটি হিপ সাইজ। সার্ভার-শ্রেণী না হলে, এটি সিরিয়াল GC-তে ডিফল্ট হবে ।
সংক্ষেপে, GC টিউনিং বেছে নিন যখন এটি স্পষ্ট যে অ্যাপ্লিকেশনটির কর্মক্ষমতা সীমাবদ্ধতা সরাসরি আবর্জনা সংগ্রহের আচরণের সাথে আবদ্ধ এবং আপনার কাছে অবগত সমন্বয় করার জন্য প্রয়োজনীয় দক্ষতা রয়েছে। অন্যথায়, JVM এর ডিফল্ট সেটিংস বিশ্বাস করুন এবং অ্যাপ্লিকেশন-স্তরের কোড অপ্টিমাইজ করার উপর ফোকাস করুন।
u/shiphe - আপনি সম্পূর্ণ মন্তব্য পড়তে চাইবেন
আপনি যদি কোনো বাস্তব বেঞ্চমার্কিং ছাড়াই অনুভূতি থেকে অপ্টিমাইজ করে থাকেন, তাহলে আপনি নিজের ক্ষতি করছেন। আপনার অ্যালগরিদমের কর্মক্ষমতা পরীক্ষা করার জন্য JMH হল ডি ফ্যাক্টো জাভা লাইব্রেরি। এটা ব্যবহার করো.
একটি নির্দিষ্ট কোরে একটি প্রক্রিয়া পিন করা ক্যাশে হিট উন্নত করতে পারে। এটি অন্তর্নিহিত হার্ডওয়্যার এবং কীভাবে আপনার রুটিন ডেটা নিয়ে কাজ করছে তার উপর নির্ভর করবে। তবুও, এই লাইব্রেরিটি বাস্তবায়ন করা এত সহজ করে তোলে যে, যদি একটি CPU-নিবিড় পদ্ধতি আপনাকে টেনে আনে, আপনি এটি পরীক্ষা করতে চাইবেন।
এটি সেই লাইব্রেরিগুলির মধ্যে একটি যা আপনার প্রয়োজন না হলেও, আপনি অধ্যয়ন করতে চাইবেন৷ ধারণাটি হল অতি-নিম্ন লেটেন্সি কনকারেন্সির জন্য অনুমতি দেওয়া। কিন্তু এটি যেভাবে বাস্তবায়িত হয়েছে, যান্ত্রিক সহানুভূতি থেকে শুরু করে রিং বাফার পর্যন্ত, অনেক নতুন ধারণা নিয়ে আসে। আমার এখনও মনে আছে যখন আমি প্রথম এটি আবিষ্কার করেছি, সাত বছর আগে, এটি হজম করার জন্য একটি অল-নাইটার টানছিল।
jvmquake
এর ভিত্তি হল যখন জিনিসগুলি JVM-এর সাথে পাশ কাটিয়ে যায়, আপনি চান যে এটি মারা যাক এবং ঝুলে না যাক। কয়েক বছর আগে, আমি একটি HTCondor ক্লাস্টারে সিমুলেশন চালাচ্ছিলাম যা মেমরির সীমাবদ্ধতায় ছিল এবং কখনও কখনও, "মেমরির বাইরে" ত্রুটির কারণে চাকরি আটকে যেত।
এই লাইব্রেরি JVM কে মারা যেতে বাধ্য করে, আপনাকে প্রকৃত ত্রুটি মোকাবেলা করার অনুমতি দেয়। এই নির্দিষ্ট ক্ষেত্রে, HTCondor কাজটি স্বয়ংক্রিয়ভাবে পুনরায় নির্ধারণ করবে।
কোড যে আমাকে এই পোস্ট লিখতে? আমি আরও খারাপ লিখেছি। আমি এখনও করি. আমরা সর্বোত্তম যা আশা করতে পারি তা হল ক্রমাগত কম জগাখিচুড়ি করা।
আমি রাস্তার নিচে কয়েক বছর আমার নিজের কোড দেখে অসন্তুষ্ট হওয়ার আশা করছি।
এবং এটি একটি ভাল লক্ষণ।
visitedCountries()
এ পরিবর্তনযোগ্যতা ত্রুটি ধরার জন্য এবং বিস্তারিত ব্যাখ্যার জন্য FlorianSchaetz-এর কাছে।এছাড়াও wasteofserver.com এ প্রকাশিত