জন স্কিটি সম্প্রতি তার ব্লগে একটি আকর্ষণীয় প্রোগ্রামিংয়ের বিষয় উত্থাপন করেছে: "আমার বিমূর্ততায় একটি গর্ত রয়েছে, প্রিয় লিজা, প্রিয় লিজা" (জোর দেওয়া হয়েছে):
আমার একটি সেট আছে - ক
HashSet
, আসলে। আমি এটি থেকে কিছু আইটেম সরাতে চাই ... এবং অনেক আইটেমের অস্তিত্ব নাও থাকতে পারে। প্রকৃতপক্ষে, আমাদের পরীক্ষার ক্ষেত্রে, "অপসারণ" সংগ্রহের কোনও আইটেম আসল সেটে থাকবে না। এই শব্দ - এবং প্রকৃতপক্ষে হয় - অত্যন্ত সহজ কোডে। সর্বোপরি, আমরাSet<T>.removeAll
আমাদের সাহায্য করব, তাই না?আমরা কমান্ড লাইনে "উত্স" সেটটির আকার এবং "অপসারণ" সংগ্রহের আকার নির্দিষ্ট করি এবং সেগুলি উভয়ই তৈরি করি। উত্স সেটটিতে কেবল অ-নেতিবাচক পূর্ণসংখ্যা রয়েছে; অপসারণের সেটগুলিতে কেবল নেতিবাচক পূর্ণসংখ্যা থাকে। আমরা পরিমাপ করেছি যে সমস্ত উপাদান ব্যবহার করে এটি সরিয়ে ফেলতে কতক্ষণ সময় লাগে
System.currentTimeMillis()
, যা বিশ্বের সবচেয়ে নিখুঁত স্টপওয়াচ নয় তবে এই ক্ষেত্রে যথেষ্ট পরিমাণের চেয়ে বেশি, আপনি দেখতে পাবেন। কোডটি এখানে:
import java.util.*; public class Test { public static void main(String[] args) { int sourceSize = Integer.parseInt(args[0]); int removalsSize = Integer.parseInt(args[1]); Set<Integer> source = new HashSet<Integer>(); Collection<Integer> removals = new ArrayList<Integer>(); for (int i = 0; i < sourceSize; i++) { source.add(i); } for (int i = 1; i <= removalsSize; i++) { removals.add(-i); } long start = System.currentTimeMillis(); source.removeAll(removals); long end = System.currentTimeMillis(); System.out.println("Time taken: " + (end - start) + "ms"); } }
আসুন এটিকে একটি সহজ কাজ দিয়ে শুরু করুন: 100 টি আইটেমের উত্স সেট, এবং সরানোর জন্য 100:
c:UsersJonTest>java Test 100 100 Time taken: 1ms
ঠিক আছে, সুতরাং আমরা এটি ধীর হওয়ার আশা করিনি ... স্পষ্টত আমরা কিছুটা র্যাম্প করতে পারি। কীভাবে এক মিলিয়ন আইটেম এবং 300,000 আইটেমগুলির উত্স সরানো হবে?
c:UsersJonTest>java Test 1000000 300000 Time taken: 38ms
হুঁ। এটি এখনও বেশ দ্রুত বলে মনে হচ্ছে। এখন আমি অনুভব করছি যে আমি কিছুটা নিষ্ঠুর হয়েছি, এটি সমস্ত অপসারণ করতে বলছি। আসুন এটি কিছুটা সহজ করুন - 300,000 উত্স আইটেম এবং 300,000 সরানো:
c:UsersJonTest>java Test 300000 300000 Time taken: 178131ms
মাফ করবেন? প্রায় তিন মিনিট ? হায়! আমরা 38ms এ যা পরিচালনা করেছি তার চেয়ে ছোট সংগ্রহ থেকে আইটেমগুলি সরিয়ে ফেলা সহজ হওয়া উচিত ?
এই ঘটনাটি কেন ঘটছে তা কেউ ব্যাখ্যা করতে পারেন? HashSet<T>.removeAll
পদ্ধতিটি এত ধীর কেন ?