संपादित
मैं अपने जवाब की एक पूरी तरह से विशेष रुप से कार्यान्वयन पर सोच रहा था, मैंने सोचा कि मैं संलग्न चाहते हैं। मुझे यकीन नहीं है कि समानांतरता मदद करेगी, शायद यह initializer
पर निर्भर करती है।
using System;
using System.Linq;
public static T[][][] NewJagged<T>(
int h,
int w,
ing d,
Func<int, int, int, T> initializer = null,
bool parallelize = true)
{
if (h < 1)
{
throw new ArgumentOutOfRangeException("h", h, "Dimension less than 1.")
}
if (w < 1)
{
throw new ArgumentOutOfRangeException("w", w, "Dimension less than 1.")
}
if (d < 1)
{
throw new ArgumentOutOfRangeException("d", d, "Dimension less than 1.")
}
if (initializer == null)
{
initializer = (i, j, k) => default(T);
}
if (parallelize)
{
return NewJaggedParalellImpl(h, w, d, initializer);
}
return NewJaggedImpl(h, w, d, initializer);
}
private static T[][][] NewJaggedImpl<T>(
int h,
int w,
int d,
Func<int, int, int, T> initializer)
{
var result = new T[h][][];
for (var i = 0; i < h; i++)
{
result[i] = new T[w][];
for (var j = 0; j < w; j++)
{
result[i][j] = new T[d];
for (var k = 0; k < d; k++)
{
result[i][j][k] = initializer(i, j, k);
}
}
}
return result;
}
private static T[][][] NewJaggedParalellImpl<T>(
int h,
int w,
int d,
Func<int, int, int, T> initializer)
{
var result = new T[h][][];
ParallelEnumerable.Range(0, h).ForAll(i =>
{
result[i] = new T[w][];
ParallelEnumerable.Range(0, w).ForAll(j =>
{
result[i][j] = new T[d];
ParallelEnumerable.Range(0, d).ForAll(k =>
{
result[i][j][k] = initializer(i, j, k);
});
});
});
return result;
}
यह समारोह पूरी तरह से सामान्य बनाता है, लेकिन अभी भी आप सरल वाक्य रचना छोड़ देता है,
var foo1 = NewJagged<Foo>(1000, 1000, 500);
लेकिन आप कल्पना हो और आरंभीकरण पर समानांतर में पॉप्युलेट सकता है,
var foo2 = NewJagged<Foo>(
1000,
1000,
5000,
(i, j, k) =>
{
var pos = (i * 1000 * 500) + (j * 500) + k;
return ((pos % 2) == 0) ? new Foo() : null;
});
इस उदाहरण में
, एक चेकरबोर्ड प्रभाव के साथ populating (मुझे लगता है।);
यह शुरू में आपकी समस्या को जवाब देने के लिए प्रतीत नहीं कर सकते हैं ...
यदि आप एक समारोह, इस
public static T[][][] ThreeDimmer<T>(int h, int w, int d) where T : new()
{
var result = new T[h][][];
for (var i = 0; i < h; i++)
{
result[i] = new T[w][];
for (var j = 0; j < w; j++)
{
result[i][j] = new T[d];
for (var k = 0; k < d; k++)
{
result[i][j][k] = new T();
}
}
}
return result;
}
की तरह कुछ था तो फिर तुम एक 3 आयामी का आरंभीकरण समझाया है | संदर्भ प्रकार के jagged सरणी। यह आपको करने की अनुमति देगा,
Foo[][][] foo1 = ThreeDimmer<Foo>(1000, 1000, 500);
यह बहुआयामी सरणी के स्मृति विखंडन के मुद्दों से बच जाएगा। यह other pitfalls and limitations से भी बच जाएगा, जिससे आप इसके बजाय एक तेज़ और अधिक लचीला जाली सरणी दे सकते हैं।
मुझे लगता है कि यदि आप 64x के लिए संकलित करते हैं तो आप ठीक होने जा रहे हैं। मुझे लगता है कि आप केवल पहले सरणी के साथ किसी ऑब्जेक्ट की सीमा पर जाते हैं। तो हाँ दो कथन मेमोरी में लगभग एक ही स्थान लेते हैं, लेकिन यह केवल इसलिए है क्योंकि आप .net की प्रति वस्तु (कम से कम 32x के लिए) पर चलते हैं –
"नया" का उपयोग करके इसे ढेर पर रखा जाएगा। जब आप इसे विभाजित करते हैं तो यह शायद काम करता है क्योंकि अब आप 500 मिलियन _contiguous_ "Foo" आकार के टुकड़े का अनुरोध नहीं कर रहे हैं। –
क्या आप वाकई वाकई सुनिश्चित हैं कि आपको 'फू' की प्री-आवंटित सरणी की आवश्यकता है।समझाएं कि आप उस आकार की सरणी का उपयोग करके क्या करने की कोशिश कर रहे हैं, इसे संभालने के बेहतर तरीके हो सकते हैं (शायद एक नेस्टेड डिक्शनरी जिसमें केवल आपके द्वारा आवश्यक आबादी वाले मूल्य शामिल हैं 'int >> ') –