एक लूप हटाएं, एक नई निर्भरता जोड़ें या दो लूप रखें
मैं C++ और Unreal इंजन 5.4.4 के साथ एक गेम विकसित कर रहा हूं।
मुझे वर्तमान में एक समस्या है कि मॉड्यूल में नई निर्भरता जोड़े बिना लूप को कैसे हटाया जाए।
अवास्तविक संबंधित कक्षाओं को समूहीकृत करने के लिए मॉड्यूल हैं। मेरे पास डेटाबेस (SQLite 3) तक पहुंचने के लिए एक मॉड्यूल है और गणितीय गणना करने के लिए एक अन्य मॉड्यूल है। सबसे पहले मैं डेटा प्राप्त करता हूं, यह सब प्राप्त करने के लिए एक लूप का उपयोग करता हूं। फिर मैं कुछ गणनाएँ करने के लिए डेटा पर वापस जाता हूँ। मेरी समस्या यह है कि इसमें बहुत सारा डेटा है, 200,000 से अधिक रिकॉर्ड और दो बार।
यदि मैं डेटाबेस विधि के अंदर गणना करता हूं, तो मैं डेटाबेस मॉड्यूल में एक निर्भरता जोड़ता हूं। लेकिन अगर मैं इसे वैसे ही छोड़ दूं, तो इसमें दोगुना समय लगता है।
इसके अलावा, मुझे नहीं लगता कि ऐसे मॉड्यूल में गणना करना सही है जिसका काम डेटाबेस से डेटा पुनर्प्राप्त करना है। या शायद यह किया जा सकता है।
आप यह कैसे करेंगे?
डेटा संरचना विवरण के बारे में कुछ नहीं जानने के कारण, मैं कहूंगा:
अलग से होना बहुत आम बात है मॉड्यूल जो डेटा एक्सेस लेयर ("रिपोजिटरी" पैटर्न) है
यदि आपको प्रत्येक रिकॉर्ड को संसाधित करना है, तो आपको उन पर लूप करना होगा - लेकिन इसका मतलब यह नहीं है कि उन सभी को मेमोरी में होना चाहिए एक ही समय जब तक कि वे एक दूसरे पर निर्भर न हों
यह इटरेटर पैटर्न के लिए यह एक सामान्य मामला है।
आप इसे दो तरीकों में से एक में कर सकते हैं। आप पुनरावृत्ति को रिपॉजिटरी में रख सकते हैं और एक कॉलबैक फ़ंक्शन कर सकते हैं जिसे प्रति-रिकॉर्ड कहा जाता है जो गणना करता है; या आपके पास रिपॉजिटरी किसी प्रकार का "परिणाम" ऑब्जेक्ट लौटाती है जो नेक्स्ट() विधि जैसा कुछ प्रदान करती है। जब तक आपके परिणाम रिकॉर्ड समाप्त नहीं हो जाते तब तक आप Next() को कॉल करते हैं।
इटरेटर पैटर्न sqlite3_step को कॉल करेगा; sqlite3_exec का कॉलबैक दूसरा तरीका है।
जब हम 200,000 रिकॉर्ड के बारे में बात कर रहे हैं तो मुझे संदेह है कि समस्या सीधे तौर पर दूसरा लूप नहीं है। ऐसा है कि आपको उन रिकॉर्ड्स को कहीं रखना होगा।
यदि आप उन्हें किसी फ़ाइल में भेज रहे हैं तो आपको एक IO हिट मिलेगी। यदि आप उन्हें स्मृति में रख रहे हैं, तो यदि आप सावधान नहीं हैं तो कैश छूटने की अच्छी संभावना है। या तो आपका समय खर्च होगा जो साधारण लूपिंग से कहीं अधिक है।
आप जो रणनीति अपना रहे हैं उसे स्लर्पिंग कहा जाता है। आप इस पर कार्रवाई करने से पहले सारा डेटा लोड कर रहे हैं। कभी-कभी इसकी आवश्यकता होती है।
सामान्य विकल्प को चंकिंग कहा जाता है। आप उतना ही पढ़ें जितना लोड करना आसान हो (डीबी और कैश सीमाओं दोनों का सम्मान करते हुए) और फिर उस हिस्से पर अपना काम करें। जब तक काम केवल इस बात पर निर्भर करता है कि टुकड़े में क्या है तब तक यह सरल है। जब काम पूरा हो जाता है तो परिणाम कहीं सुरक्षित रख दिया जाता है, इससे अगला हिस्सा प्राप्त करने में कोई बाधा नहीं आएगी। यदि यह बचत इतनी छोटी है कि यह डीबी, फ़ाइल सिस्टम, नेटवर्क को हिट नहीं करती है, या कैश मिस का कारण नहीं बनती है तो आप यहां कुछ वास्तविक बचत देख सकते हैं।
कभी-कभी जब आप आगे बढ़ते हैं तो कुछ संचय स्थिति की आवश्यकता होती है टुकड़े-टुकड़े करके टुकड़े-टुकड़े करना। यह तब तक ठीक है जब तक यह कैश मिस होने के लिए आवश्यक मेमोरी को पर्याप्त रूप से नहीं बढ़ाता है।
बड़े O नोटेशन का अध्ययन करने वाले बहुत से लोग समय चक्र पर ध्यान केंद्रित करते हैं। वे भूल जाते हैं कि बड़े O का उपयोग अंतरिक्ष के लिए भी किया जा सकता है। जो आपको धीमा भी कर सकता है. आप उनके बीच व्यापार कर सकते हैं. इसे वास्तव में समय-अंतरिक्ष व्यापार बंद कहा जाता है।
टिप्पणियों में मुझे कुछ भ्रम दिखाई दे रहा है कि यह केवल संपूर्ण के एक छोटे से हिस्से पर कार्य कर रहा है जैसा कि पुनरावृत्तियों के साथ किया जाता है। हालांकि इसे काम करने के लिए कृपया समझें कि यदि आप सारा काम मेमोरी में डंप कर देते हैं तो एक समय में थोड़ा-थोड़ा करने से मदद नहीं मिलती है।
महत्वपूर्ण बात यह है कि मेमोरी फ़ुटप्रिंट को इससे आगे न बढ़ने दें कैश में क्या फिट बैठता है।
alibabacloud.com - कैश एक्सेस विलंबता को मापने के पीछे का तंत्र
आप एक बार में जितना अधिक लोड करेंगे, इसका उपयोग करने में उतना ही अधिक समय लगेगा।< br>
इससे निपटने का सामान्य तरीका है निश्चित है कि जो लोड किया जा रहा है, अंततः, जो पहले लोड किया गया था, उस पर कदम रखेगा। इस तरह से मेमोरी फ़ुटप्रिंट मनमाने ढंग से बड़ा नहीं हो सकता।
तो ऐसा नहीं है कि आपने इटरेटर का उपयोग किया है या नहीं। यह वह जगह है जहां आप यह सारी चीजें रख रहे हैं।