C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Part 1: First we create a jagged array of int elements. The array has 3 rows—so it can have 3 subarrays once they are all assigned.
Int, uintPart 2: We assign the indexes to new int arrays. We only have an array of empty references—new arrays must be created for the rows.
Part 3: We examine each item in the jagged array. We call Length first on the array of references, and iterate through the rows.
Part 4: Here we iterate over the inner arrays (the columns) and print all the element values to the screen.
ConsoleC# program that creates jagged array
using System;
class Program
{
static void Main()
{
// Part 1: declare local jagged array with 3 rows.
int[][] jagged = new int[3][];
// Part 2: create a new array in the jagged array.
jagged[0] = new int[2];
jagged[0][0] = 1;
jagged[0][1] = 2;
jagged[1] = new int[1];
jagged[2] = new int[3] { 3, 4, 5 };
// Part 3: iterate overall the elements.
for (int i = 0; i < jagged.Length; i++)
{
// Part 4: iterate over the inner array.
// ... Print all its elements.
int[] innerArray = jagged[i];
for (int a = 0; a < innerArray.Length; a++)
{
Console.Write(innerArray[a] + " ");
}
Console.WriteLine();
}
}
}
Output
1 2
0
3 4 5
And: If so, you can consider 2D arrays, but often you have varying numbers of elements.
Performance: Jagged arrays are faster and have different syntax. They are faster because they use the "newarr", vector IL calls internally.
Zero index: The boost in performance with jagged arrays is because they are optimized for starting at 0 indexes.
IL: newarrIL DisassemblerMethod that is reflected for MSIL test: C#
private static void CompareIL()
{
int[,] twoD = new int[1, 1]; // 1 x 1 array
twoD[0, 0] = 1;
int[][] jag = new int[1][];
jag[0] = new int[1];
jag[0][0] = 1; // 1 x 1 jagged array
}
PrintFirstElement: This receives a jagged array. The string data is not copied when it is called—just the reference to that data is copied.
C# program that shows jagged array argument
using System;
class Program
{
static void PrintFirstElement(string[][] values)
{
// Only the reference is copied when this method is called with an array.
Console.WriteLine(values[0][0]);
}
static void Main()
{
PrintFirstElement(new string[][] {
new string[] { "bird", "frog" },
new string[] { "cat", "dog" }});
}
}
Output
bird
Version 1: This code accesses the elements in a 2D array. It loops over elements with a for-loop.
ForVersion 2: This version of the code accesses the elements of a jagged array in a for-loop.
Result: Jagged have substantial optimizations in the intermediate language level. This can be exploited to speed up programs.
C# program that benchmarks 2D, jagged arrays
using System;
using System.Diagnostics;
class Program
{
const int _max = 100000;
static void Main()
{
// Set up data.
var a1 = new int[100, 100];
var a2 = new int[100][];
for (int i = 0; i < 100; i++)
{
a2[i] = new int[100];
}
// Version 1: access 2D array.
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
for (int a = 0; a < 100; a++)
{
for (int x = 0; x < 100; x++)
{
int c = a1[a, x];
}
}
}
s1.Stop();
// Version 2: access jagged array.
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
for (int a = 0; a < 100; a++)
{
for (int x = 0; x < 100; x++)
{
int c = a2[a][x];
}
}
}
s2.Stop();
// Results.
Console.WriteLine(s1.Elapsed.TotalMilliseconds);
Console.WriteLine(s2.Elapsed.TotalMilliseconds);
}
}
Output
2D array access: 1286.5545 ms
Jagged array access: 486.7875 ms
Version 1: Here we allocate 2D arrays. A 2D array only requires 1 allocation, and can be garbage-collected easier as well.
Version 2: In this version of the code we allocate jagged arrays in a tight loop. More allocations must occur.
Result: It is faster to allocate the space in the form of a 2D array. The jagged array could be allocated lazily, which might be better.
C# program that benchmarks 2D, jagged array allocation
using System;
using System.Diagnostics;
class Program
{
const int _max = 100000;
static void Main()
{
// Version 1: create 2D array.
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Create2DArray();
}
s1.Stop();
// Version 2: create jagged array.
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
CreateJaggedArray();
}
s2.Stop();
// Print times.
Console.WriteLine(s1.Elapsed.TotalMilliseconds);
Console.WriteLine(s2.Elapsed.TotalMilliseconds);
}
static int[][] CreateJaggedArray()
{
var array = new int[100][];
for (int i = 0; i < 100; i++)
{
array[i] = new int[100];
}
return array;
}
static int[,] Create2DArray()
{
var array = new int[100, 100];
return array;
}
}
Output
2D array allocation: 202.1575 ms
Jagged array allocation: 452.0066 ms
Version 1: This measures the memory use of a jagged array of 1000 sub-arrays. The memory size (measured with GetTotalMemory) is printed.
GC.CollectVersion 2: This measures the memory of a 2D array of the same element count as the jagged array in version 1. It uses less memory.
Result: For rectangular shapes, prefer a 2D array for best memory compactness. Fewer bytes per element are used.
Important: If your data is truly "jagged" or uneven in the lengths of subarrays, a jagged array may be far superior in memory use.
C# program that measures jagged array memory
using System;
class Program
{
static void Main()
{
long b1 = GC.GetTotalMemory(true);
// Version 1: test memory usage of a jagged array.
int[][] jagged = new int[1000][];
for (int i = 0; i < 1000; i++)
{
jagged[i] = new int[100];
}
long b2 = GC.GetTotalMemory(true);
jagged[0][0] = 0;
Console.WriteLine("{0} bytes (jagged 1000 x 100)", b2 - b1);
}
}
Output
416028 bytes (jagged 1000 x 100)
C# program that measures 2D array memory
using System;
class Program
{
static void Main()
{
long b1 = GC.GetTotalMemory(true);
// Version 2: test memory usage of a two-dimensional array.
int[,] array = new int[1000, 100];
long b2 = GC.GetTotalMemory(true);
array[0, 0] = 0;
Console.WriteLine("{0} bytes (2D 1000 x 100)", b2 - b1);
}
}
Output
400032 bytes (2D 1000 x 100)