जॉन स्कीट ने हाल ही में अपने ब्लॉग पर एक दिलचस्प प्रोग्रामिंग विषय उठाया: "मेरे अमूर्त में एक छेद है, प्रिय लिजा, प्रिय लिजा" (जोर दिया):
मेरे पास एक सेट है -
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
विधि इतनी धीमी क्यों है ?