2011-05-10 14 views
13

मैं एक 2 डी सरणी को एक ही मान के साथ भरना चाहता हूं, हालांकि, मैं इसे सबसे तेज़ तरीका करना चाहता हूं जिसमें 2 डी सरणी की लंबाई कुल होगी 200k + और समय के साथ इन 200ों में से अधिक arrays होंगे। मैंने बफर में देखा है। ब्लॉककॉपी और ऐरे। कॉपी, हालांकि, वे दोनों स्रोत/गंतव्य के रूप में सरणी लेते हैं, जहां मेरे पास एकमात्र सरणी गंतव्य है, स्रोत एक ही मूल्य है।एक मान के साथ एक सरणी को भरने का सबसे तेज़ तरीका

स्रोत के साथ एक सरणी भरने का सबसे तेज़ तरीका क्या है, एक सरणी नहीं है?

+0

अलग-अलग तरीके के एक जोड़े, इस आदमी को बाहर अधिक आम लोगों के कुछ सूचीबद्ध किया है कर रहे हैं - और वह इसे बेंचमार्क भी तरह पर्याप्त था: http://www.dotnetperls.com/initialize-array स्मृति में 200K आइटम होल्डिंग, भले ही वे प्राइमेटिव हैं, मेमोरी का एक बड़ा हिस्सा खाने जा रहा है - आप क्या कर रहे हैं कि आपको निरंतर 200K आइटम उपलब्ध हैं समय का उपयोग (प्रति आइटम)? – debracey

+0

एक डुप्लिकेट प्रश्न नहीं हो सकता है, उसने यह नहीं कहा था कि वह इसके साथ सरणी को इंटिलाइज़ करना चाहता था, जैसा कि वीलेयू – user613326

उत्तर

1

कुछ संबंधित जानकारी के लिए, What is the equivalent of memset in C#? देखें।

जैसा कि उस प्रश्न में उल्लिखित है (इस के एक डुप्लिकेट के बहुत करीब), लूप आमतौर पर सबसे अच्छा है जब तक आप unmanaged code में नहीं जाना चाहते हैं।

तो यह बहुत तेजी से किया जाना चाहिए:

int[] arr = new int[MAX_ELEMENTS]; 
for (int i = 0; i < arr.Length; ++i) 
{ 
    array[i] = MY_VALUE; 
} 

सब बातों के साथ के रूप में प्रदर्शन से संबंधित है, कुछ काम कर रहे हो, तो उपाय क्या अड़चन है। "उपाय" पर जोर। अनुमान लगाना क्या अड़चन है कोशिश कर रहा है आम तौर पर एक बुरा विचार (है:।

1

Array.Copy बेहतर पाश के लिए एक से अनुकूलित हो, तो यह उपयोग करने के लिए की संभावना है

void FillArray<T>(T[] arr, T fillValue) 
{ 
    int i = 0; 
    if (arr.Length > 16) { 
    { 
     do { 
      array[i++] = fillValue; 
     } while (i < arr.Length) 
     while (i + 16 < arr.Length) { 
      Array.Copy(arr, 0, arr, i, 16); 
      i = i + 16; 
     } 
    } 
    while (i < arr.Length) 
    { 
     array[i++] = fillValue; 
    } 
} 

(मैं एक प्रदर्शन को देखने के लिए अच्छा लगेगा विभिन्न प्रकार और सरणी आकारों के लिए लूप के लिए इस और बेवकूफ के बीच तुलना)

8

मैंने पाया है कि सबसे तेज़ तरीका ऐरे का उपयोग करता है। कॉपी आकार के साथ प्रत्येक बार लूप के माध्यम से दोगुनी हो जाती है। गति मूल रूप से वही होती है चाहे आप भरें एक मान या मूल्यों की सरणी वाला सरणी।

20,000,000 सरणी वस्तुओं के साथ मेरे परीक्षण में, यह फ़ंक्शन लूप के रूप में दोगुना तेज़ है।

using System; 

namespace Extensions 
{ 
    public static class ArrayExtensions 
    { 
     public static void Fill<T>(this T[] destinationArray, params T[] value) 
     { 
      if (destinationArray == null) 
      { 
       throw new ArgumentNullException("destinationArray"); 
      } 

      if (value.Length >= destinationArray.Length) 
      { 
       throw new ArgumentException("Length of value array must be less than length of destination"); 
      } 

      // set the initial array value 
      Array.Copy(value, destinationArray, value.Length); 

      int arrayToFillHalfLength = destinationArray.Length/2; 
      int copyLength; 

      for(copyLength = value.Length; copyLength < arrayToFillHalfLength; copyLength <<= 1) 
      { 
       Array.Copy(destinationArray, 0, destinationArray, copyLength, copyLength); 
      } 

      Array.Copy(destinationArray, 0, destinationArray, copyLength, destinationArray.Length - copyLength); 
     } 
    } 
} 

मैं http://coding.grax.com/2011/11/initialize-array-to-value-in-c-very.html पर इस बारे में भी ब्लॉग और http://coding.grax.com/2014/04/better-array-fill-function.html

+2

के साथ बड़े हिस्से के लिए सरणी भरने का स्वागत है, मुझे एक सरणी भरनी होगी, इसलिए मैंने आपकी ' Fill' विस्तार और भरें (इस टी [,] destinationArray, टी [,] मूल्य) ' ' public static void के लिए हस्ताक्षर बदल गया है और तरह तो यह कहा जाता है: 'myLargeArray.Fill (नई [] {{double.NaN}, {double.NaN}}); ' और यह ठीक काम करता है। धन्यवाद! – Kaboo

संबंधित मुद्दे