Сначала вам не нужен навигатор; SelectNodes / SelectSingleNode должен быть достаточным.
Однако вам может понадобиться менеджер пространства имен - например:
XmlElement el = ...; //TODO
XmlNamespaceManager nsmgr = new XmlNamespaceManager(
el.OwnerDocument.NameTable);
nsmgr.AddNamespace("x", el.OwnerDocument.DocumentElement.NamespaceURI);
var nodes = el.SelectNodes(@"/x:outerelement/x:innerelement", nsmgr);
Массив массивов (зубчатые массивы) быстрее, чем многомерные массивы и может использоваться эффективнее. Многомерные массивы имеют более хороший синтаксис.
, Если Вы пишете некоторому простому использованию кода зубчатые и многомерные массивы и затем осматриваете скомпилированный блок с дизассемблером IL, Вы будете видеть, что устройство хранения данных и извлечение от зубчатого (или единственный размерный) массивы являются простыми инструкциями IL, в то время как те же операции для многомерных массивов являются вызовами метода, которые всегда медленнее.
Рассматривают следующие методы:
static void SetElementAt(int[][] array, int i, int j, int value)
{
array[i][j] = value;
}
static void SetElementAt(int[,] array, int i, int j, int value)
{
array[i, j] = value;
}
Их IL будет следующим:
.method private hidebysig static void SetElementAt(int32[][] 'array',
int32 i,
int32 j,
int32 'value') cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldelem.ref
IL_0003: ldarg.2
IL_0004: ldarg.3
IL_0005: stelem.i4
IL_0006: ret
} // end of method Program::SetElementAt
.method private hidebysig static void SetElementAt(int32[0...,0...] 'array',
int32 i,
int32 j,
int32 'value') cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: ldarg.3
IL_0004: call instance void int32[0...,0...]::Set(int32,
int32,
int32)
IL_0009: ret
} // end of method Program::SetElementAt
, Когда использование неровно оборвало массивы, можно легко выполнить такие операции, как подкачка строки и строка изменяют размеры. Возможно, в некоторых случаях использование многомерных массивов будет более безопасным, но даже Microsoft FxCop сообщает, что зубчатые массивы должны использоваться вместо многомерного при использовании его для анализа проектов.
Многомерный массив создает хорошее линейное расположение памяти, в то время как зубчатый массив подразумевает несколько дополнительных уровней абстракции.
Поиск значения jagged[3][6]
в зубчатом массиве var jagged = new int[10][5]
работы как это: Ищите элемент в индексе 3 (который является массивом), и ищите элемент в индексе 6 в том массиве (который является значением). Для каждого размера в этом случае, существует дополнительный взгляд (это - дорогой шаблон доступа к памяти).
многомерный массив А размечается линейно в памяти, фактическое значение найдено путем умножения вместе индексов. Однако, учитывая массив var mult = new int[10,30]
, Length
свойство того многомерного массива возвращает общее число элементов т.е. 10 * 30 = 300.
Rank
свойство зубчатого массива всегда равняется 1, но многомерный массив может иметь любой разряд. GetLength
метод любого массива может использоваться для получения длины каждого размера. Для многомерного массива в этом примере mult.GetLength(1)
возвраты 30.
Индексация многомерного массива быстрее. например, учитывая многомерный массив в этом примере mult[1,7]
= 30 * 1 + 7 = 37, получите элемент в том индексе 37. Это - лучший шаблон доступа к памяти, потому что только одна ячейка памяти включена, который является базовым адресом массива.
многомерный массив А поэтому выделяет непрерывный блок памяти, в то время как зубчатый массив не должен быть квадратным, например, jagged[1].Length
не должен равняться jagged[2].Length
, который был бы верен для любого многомерного массива.
Производительность мудрые, многомерные массивы должны быть быстрее. Намного быстрее, но из-за действительно плохой реализации CLR они не.
23.084 16.634 15.215 15.489 14.407 13.691 14.695 14.398 14.551 14.252
25.782 27.484 25.711 20.844 19.607 20.349 25.861 26.214 19.677 20.171
5.050 5.085 6.412 5.225 5.100 5.751 6.650 5.222 6.770 5.305
первая строка является синхронизациями зубчатых массивов, вторых выставочных многомерных массивов и третьего, хорошо это - то, как это должно быть. Программу показывают ниже, к вашему сведению это было протестировано, работая моно. (Синхронизации окон весьма отличаются, главным образом из-за изменений реализации CLR).
окна On, синхронизации зубчатых массивов значительно выше о том же как моя собственная интерпретация того, какой многомерный массив ищут, должен быть похожим, видеть 'Единственный ()'. Печально JIT-компилятор окон действительно глуп, и это, к сожалению, делает эти обсуждения производительности трудными, существует слишком много несоответствий.
Это синхронизации, я вошел в окна, то же соглашение здесь, первая строка являются зубчатыми массивы, вторые многомерный и третий моя собственная реализация многомерных, отмечают, насколько медленнее это находится на окнах по сравнению с моно.
8.438 2.004 8.439 4.362 4.936 4.533 4.751 4.776 4.635 5.864
7.414 13.196 11.940 11.832 11.675 11.811 11.812 12.964 11.885 11.751
11.355 10.788 10.527 10.541 10.745 10.723 10.651 10.930 10.639 10.595
Исходный код:
using System;
using System.Diagnostics;
static class ArrayPref
{
const string Format = "{0,7:0.000} ";
static void Main()
{
Jagged();
Multi();
Single();
}
static void Jagged()
{
const int dim = 100;
for(var passes = 0; passes < 10; passes++)
{
var timer = new Stopwatch();
timer.Start();
var jagged = new int[dim][][];
for(var i = 0; i < dim; i++)
{
jagged[i] = new int[dim][];
for(var j = 0; j < dim; j++)
{
jagged[i][j] = new int[dim];
for(var k = 0; k < dim; k++)
{
jagged[i][j][k] = i * j * k;
}
}
}
timer.Stop();
Console.Write(Format,
(double)timer.ElapsedTicks/TimeSpan.TicksPerMillisecond);
}
Console.WriteLine();
}
static void Multi()
{
const int dim = 100;
for(var passes = 0; passes < 10; passes++)
{
var timer = new Stopwatch();
timer.Start();
var multi = new int[dim,dim,dim];
for(var i = 0; i < dim; i++)
{
for(var j = 0; j < dim; j++)
{
for(var k = 0; k < dim; k++)
{
multi[i,j,k] = i * j * k;
}
}
}
timer.Stop();
Console.Write(Format,
(double)timer.ElapsedTicks/TimeSpan.TicksPerMillisecond);
}
Console.WriteLine();
}
static void Single()
{
const int dim = 100;
for(var passes = 0; passes < 10; passes++)
{
var timer = new Stopwatch();
timer.Start();
var single = new int[dim*dim*dim];
for(var i = 0; i < dim; i++)
{
for(var j = 0; j < dim; j++)
{
for(var k = 0; k < dim; k++)
{
single[i*dim*dim+j*dim+k] = i * j * k;
}
}
}
timer.Stop();
Console.Write(Format,
(double)timer.ElapsedTicks/TimeSpan.TicksPerMillisecond);
}
Console.WriteLine();
}
}
Массивы мультиразмера (n-1) - матрицы размера.
Так int[,] square = new int[2,2]
квадратная матрица 2x2, int[,,] cube = new int [3,3,3]
куб - квадратная матрица 3x3. Пропорциональность не требуется.
Зубчатые массивы являются просто массивом массивов - массив, где каждая ячейка содержит массив.
Так MDA пропорциональны, JD может быть нет! Каждая ячейка может содержать массив произвольной длины!
Просто поместите многомерные массивы, подобны таблице в DBMS.
Массив Массива (зубчатый массив) позволяет, Вы иметь каждый элемент держите другой массив того же типа переменной длины.
Так, если Вы уверены, что структура данных похожа на таблицу (зафиксированные строки/столбцы), можно использовать многомерный массив. Зубчатый массив является зафиксированными элементами & каждый элемент может содержать массив переменной длины
, Например, Psuedocode:
int[,] data = new int[2,2];
data[0,0] = 1;
data[0,1] = 2;
data[1,0] = 3;
data[1,1] = 4;
Думают о вышеупомянутом как 2x2 таблица:
1 | 2 3 | 4
int[][] jagged = new int[3][];
jagged[0] = new int[4] { 1, 2, 3, 4 };
jagged[1] = new int[2] { 11, 12 };
jagged[2] = new int[3] { 21, 22, 23 };
Думают о вышеупомянутом как о каждой строке, имеющей переменное число столбцов:
1 | 2 | 3 | 4 11 | 12 21 | 22 | 23