वेक्टर 3 को वेक्टर 2 में बदलने का सबसे कुशल तरीका


11

वेक्टर 3 को वेक्टर 2 में बदलने का सबसे कुशल और सबसे तेज़ तरीका क्या है?

कास्टिंग:

Vector2 vector2 = (Vector2)vector3;

एक नया वेक्टर 2 शुरू करना:

Vector2 vector2 = new Vector2(vector3.x, vector3.y);

या वहाँ एक और तरीका है जो मुझे नहीं पता है?


11
आपके खेल में इस प्रकार के संरचना संचालन कभी भी प्रदर्शन-निर्धारित करने वाले अड़चन के रूप में नहीं होते हैं, इसलिए इस तरह की सूक्ष्म-अनुकूलन में गड़बड़ी होने के बजाय, मैं आपको सलाह दूंगा कि आप जिस संदर्भ का उपयोग कर रहे हैं उसे समझने के लिए जो भी स्पष्ट हो यह। ;)
DMGregory

3
@DMGregory: जब तक, बेशक, ओपी पहले ही एक प्रदर्शन विश्लेषण कर चुका होता है और शायद बॉक्सिंग के कारण, वास्तव में यह नेस्टेड लूप में होता है जिससे प्रदर्शन की समस्या होती है। इस तरह के एक नेस्टेड लूप, उदाहरण के लिए, ए-स्टार या डीजकस्ट्रा कार्यान्वयन हो सकता है।
बजे पीटर गेकर्न्स

5
@PieterGeerkens मेला, लेकिन अगर ओपी पहले से ही प्रदर्शन विश्लेषण कर रहे थे, तो वे पहले से ही दोनों तरीकों की कोशिश करेंगे और दोनों पर नंबर होंगे। ;) नए यूनिटी उपयोगकर्ताओं (स्वयं सहित) की एक संख्या के प्रक्षेपवक्र को देखने से, मुझे पूरा विश्वास है कि इस मामले में यह माइक्रो-ऑप्टिमाइज़ेशन है, इसलिए मैं इसके खिलाफ एक मजबूत (यदि संभवतः ओवरस्टेटेड) चेतावनी देना चाहता था। इस तरह से हफ्तों या महीनों के कोड में झटके आते हैं और उन तरीकों पर श्रेष्ठता होती है जो हमारे खेलों को बेहतर नहीं बनाते हैं।
DMGregory

जवाबों:


12
Vector3 v3 = Vector3.one;
Vector2 v2 = v3;

वेक्टर 3 को स्पष्ट रूप से वेक्टर 2 में परिवर्तित किया जा सकता है (जेड खारिज कर दिया गया है)।

http://docs.unity3d.com/ScriptReference/Vector2-operator_Vector3.html

यदि आपको बहुत सारे रूपांतरण करने हैं तो आपको अपने वैक्टर का उपयोग करने के तरीके को बदलना पड़ सकता है। दो परीक्षण करें और उन्हें देखने के लिए कि कौन सा आपके लिए काम करता है।

TESTS के साथ अद्यतन करें: चूंकि आपने पूछा था कि कौन सा सबसे तेज है, मैंने यूनिटी में प्रत्येक के 10000000 रूपांतरण चलाने वाला एक परीक्षण बनाया। ऐसा प्रतीत होता है कि प्रारंभिक संस्करण इस मामले में सबसे तेज है। लेकिन, आपको हमेशा उसी का उपयोग करना चाहिए जो आपके स्वयं के संदर्भ के अनुकूल हो, इसलिए मैं आपको सलाह देता हूं कि आप अपने खेल में अपने परीक्षण चलाएं।

TestConvertByOperation 10000000 उदाहरण: 0.2714049s

TestConvertByCasting 10000000 उदाहरण: 0.286027s

TestConvertByInitializing 10000000 उदाहरण: 0.1458781s

using UnityEngine;

public class TestVector3Conversion : MonoBehaviour
{

    readonly int iterations = 10000000;
    Vector3 testVector = new Vector3(3f, 14f, 42f);

    void Start()
    {
        Debug.Log(string.Format("TestConvertByOperation {0} instances: {1}s", iterations, TestConvertByOperation()));
        Debug.Log(string.Format("TestConvertByCasting {0} instances: {1}s", iterations, TestConvertByCasting()));
        Debug.Log(string.Format("TestConvertByInitializing {0} instances: {1}s", iterations, TestConvertByInitializing()));
    }

    float TestConvertByOperation()
    {
        var timeStart = Time.realtimeSinceStartup;

        for (int i = 0; i < iterations; i++)
        {
            Vector2 v2 = testVector;
        }

        return Time.realtimeSinceStartup - timeStart;
    }

    float TestConvertByCasting()
    {
        var timeStart = Time.realtimeSinceStartup;

        for (int i = 0; i < iterations; i++)
        {
            Vector2 v2 = (Vector2)testVector;
        }

        return Time.realtimeSinceStartup - timeStart;
    }

    float TestConvertByInitializing()
    {
        var timeStart = Time.realtimeSinceStartup;

        for (int i = 0; i < iterations; i++)
        {
            Vector2 v2 = new Vector2(testVector.x, testVector.y);
        }

        return Time.realtimeSinceStartup - timeStart;
    }

}

1
वे निहित हैं। यह नए रूपांतरण ऑपरेटरों को परिभाषित करके किया जाता है । विडंबना से एकता का उल्लंघन होता है '... यदि रूपांतरण की गारंटी है तो डेटा के नुकसान का कारण नहीं होगा।' अंश।
एथोस vk

1
विभिन्न दृष्टिकोणों का परीक्षण करने के लिए एक कोड उदाहरण के साथ मेरे उत्तर को अपडेट किया। मुझे बताएं कि आपके मामले में कौन सा तेज है।
मैटिस

1
परिणाम एक रिलीज़ / गैर-डिबग बिल्ड में थोड़ा बदलाव करते हैं, या जब वेक्टर 2 डेटा में लूप के लिए जीवनकाल होता है (जो कुछ प्रकार के अनुकूलन करने से कंपाइलर रखता है)। मुझे 110 से 151 मिलीसेकंड का फैलाव मिलता है, या प्रति असाइनमेंट में लगभग 4 नैनोसेकंड का अधिकतम अंतर । इसलिए जब तक हम हर फ्रेम के सैकड़ों बार ऐसा नहीं कर रहे हैं, तब तक शायद यह चिंता करने का मामला नहीं है, भले ही इस तरह के सिंथेटिक उदाहरण में एक औसत दर्जे का अंतर हो।
DMGregory

1
@DMGregory सहमत हैं। यही कारण है कि वास्तविक डेटा के साथ, सही संदर्भ में प्रदर्शन परीक्षण चलाने के लिए हमेशा एक अच्छा विचार है।
मटियास

1
अंतर्निहित रूपांतरण के साथ समस्या यह है कि yऊपर है। ए Vector3को ए में परिवर्तित करते समय Vector2, आप लगभग हमेशा चाहते हैं xऔर z, नहीं xऔर y
केविन क्रुमविडे

6

दोनों वेक्टर 2 और वेक्टर 3 एकता इंजन में एक संरचना है, इसलिए एक से दूसरे के निर्माण में बस स्टैक पर भंडारण का आवंटन शामिल है (जब तक कि गंतव्य एक क्लास ऑब्जेक्ट की विशेषता नहीं है , जो इस पहले चरण को छोड़ देगा) और दो घटक मूल्यों की नकल। आपके द्वारा दिए गए दोनों तंत्रों को वास्तव में इस IL कोड के लिए संकलित किया जाना चाहिए।

यदि आप इस प्रकार के रूपांतरण के साथ एक प्रदर्शन समस्या का सामना कर रहे हैं, तो आपके पास संभवतः एक बॉक्सिंग मुद्दा है, जिसमें संरचना को एक वर्ग ऑब्जेक्ट से परिवर्तित किया जा रहा है । उस स्थिति में आपको जांचना चाहिए कि क्या, कब और कैसे, मुक्केबाजी को आपके कोड के प्रदर्शन-महत्वपूर्ण भागों में टाला जा सकता है।


0

मेरे परीक्षण से, इसे करने का सबसे अच्छा तरीका है मैनुअल अपने मूल्य को स्वयं द्वारा निर्दिष्ट करना।

Vector2 vector2;
vector2.x = vector3.x;
vector2.y = vector3.y;

यह मेरा परिणाम है कि मैं मैटियास से विस्तार करता हूं।

TestConvertByOperation 10000000 उदाहरण: 0.3220527s

TestConvertByCasting 10000000 उदाहरण: 0.3226218s

TestConvertByInitializing 10000000 उदाहरण: 0.1916729s

TestConvertByManualAssign 10000000 उदाहरण: 0.09500527s

using UnityEngine;

namespace myTest
{
    public class test: MonoBehaviour 
    {
        readonly int iterations = 10000000;
        Vector3 testVector = new Vector3(3f, 14f, 42f);

        void Start()
        {
            Debug.Log(string.Format("TestConvertByOperation {0} instances: {1}s", iterations, TestConvertByOperation()));
            Debug.Log(string.Format("TestConvertByCasting {0} instances: {1}s", iterations, TestConvertByCasting()));
            Debug.Log(string.Format("TestConvertByInitializing {0} instances: {1}s", iterations, TestConvertByInitializing()));
            Debug.Log(string.Format("TestConvertByManualAssign {0} instances: {1}s", iterations, TestConvertByManualAssign()));
        }

        float TestConvertByOperation()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2 = testVector;
            }

            return Time.realtimeSinceStartup - timeStart;
        }

        float TestConvertByCasting()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2 = (Vector2)testVector;
            }

            return Time.realtimeSinceStartup - timeStart;
        }

        float TestConvertByInitializing()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2 = new Vector2(testVector.x, testVector.y);
            }

            return Time.realtimeSinceStartup - timeStart;
        }
        float TestConvertByManualAssign()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2.x = testVector.x;
                v2.y = testVector.y;
            }

            return Time.realtimeSinceStartup - timeStart;
        }
    }
}

कृपया ध्यान दें, मैं इसे एकता संस्करण 5.6.5 के साथ परीक्षण करता हूं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.