@ACfsDBCDesrsfXWYC| G5799964VC~WB-~CWB~~YP5656WBW 665656F4AWC 6565655F4A-~B~CC 64} 64V-

Jagged arrays.` Consider a city skyline: each tower is a different height. Suppose we represent the floors in an array. A 2D array would have wasted space. A jagged array would be best.`With jagged arrays,` we can store (efficiently) many rows of varying lengths. No space (on the tops of the skyscrapers) is wasted. Any type of data—reference or value—can be used.`First example.` Let us start. This code is a short (but complete) program you can run in a console project. It creates a jagged array of int elements. `It sets values in the array. The program then prints out the result at the end.`Arrays `array`Int `int`Important: `Jagged arrays have different performance characteristics. Indexing jagged arrays is fast. Allocating them is somewhat slow.`Notes, above example.` This example declares a jagged array. The word jagged doesn't exist in the C# language. This means that you don't need to use this word in your code. `Info: `The program initializes some values in the jagged array. There are lots of square brackets.`Syntax: `This is different from a 2D array, which uses commas instead of pure brackets.`Notes, continued.` Indexes in the array are assigned to new int arrays. The earlier statement allocates only the list of empty references. You have to make your own arrays to put in it. `We see the array initializer syntax here, which is less verbose than some other ways.`Initialize Array `initialize-array`Notes, loops.` You will want to examine each item in the jagged array. We must call Length first on the array of references, and then again on each inner array. `Syntax: `It is important to know that the pairs of brackets indicate "jagged," and the comma in the brackets means "2D".`You can allocate different arrays for each row in jagged arrays separately. This means your program must use 1D arrays in parts.`2D arrays.` We determine how to choose between jagged arrays and 2D arrays. First ask the question: will every row in my collection have the same number of elements? `If so, you can consider 2D arrays, but often you have varying numbers of elements.`2D Array `2d`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: newarr `il`IL Disassembler `il-disassembler`Methods.` You can use the type of the jagged array in method signatures. They will be passed as references. This eliminates most copying. Only the reference is copied on each function call. `For local variables only, you can use the var implicit type syntax. This makes programs easier to read.`Var `var`Benchmark, element access.` The .NET Framework has optimizations for single-dimension arrays within a jagged array. A 2D array cannot take advantage of them. `Thus: `Jagged have substantial optimizations in the intermediate language level. This can be exploited to speed up programs.`Benchmark, allocation.` Consider a space of 100 by 100 elements. We can allocate 100 separate arrays in a jagged array (101 arrays total), or use a single 2D array (1). `Info: `The 2D array only requires 1 allocation, and can be garbage-collected easier as well.`Results: `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.`Benchmark, memory use.` A jagged array will use more memory than a 2D array assuming all sub-arrays are allocated. Here we see 2 programs that test memory use. `Program 1: `This measures the memory use of a jagged array of 1000 sub-arrays. The memory size (measured with GetTotalMemory) is printed.`GC.Collect `gc-collect`Program 2: `This measures the memory of a 2D array of the same element count as the jagged array in program 1. It uses less memory.`Info: `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.`Performance, review.` Element access in jagged arrays is faster than in 2D arrays. But to allocate a large space at once, 2D arrays are a better choice.`A summary.` Jagged arrays are fast and easy to use once you learn the syntax. Prefer them to 2D arrays when performance is key. Be careful of excess memory usage.

XYZ YPYOYSYDY; { XY$X{Z XXY{Declare local jagged YT with 3 rows. XXZY}[][]Z jaggedYzZnewZ Y}[3][];Z XXY{CY` a YwYTYkthe jagged YT,YRassign it. XXZjagged[0]YzZnewZ Y}[2]; XXjagged[0][0]Yz1; XXjagged[0][1]Yz2;Z XXY{Set second row, initializedYlzero. XXZjagged[1]YzZnewZ Y}[1];Z XXY{Set third row, YPYT initializer. XXZjagged[2]YzYwZY}Z[3] { 3, 4, 5 };Z XXY{PrYsout all Y6sYkthe jagged YT. XXZYo(YsiYz0; i < jagged.LYZ; i++) XX{Y'Y}[] innerYUYzjagged[i];Y'Yo(YsaYz0; a < innerYU.LYZ; a++)Y'{Y'XY4.Yh(innerYU[a]YyZ" "Z);Y'}Y'Y%); XX} X} } Z 1 2 0 3 4 5ZMY[ that is reflected YoMSIL test: C#Z Y: YAYfCompareIL() { XZY}[,]Z twoDYzYwY}[1, 1];Z Y{1 x 1 YT XZtwoD[0, 0]Yz1YSXZY}[][]Z jagYzYwY}[1][]YSXjag[0]YzYwY}[1]; Xjag[0][0]Yz1;Z Y{1 x 1 jagged YT Z}Z YPYO; Y! YDY; { Xconst Ys_maxYz100000; XY$X{Z XXY{Set up data. XXZvar a1YzYwY}[100, 100]; XXvar a2YzYwY}[100][]; XXYo(YsiYz0; i < 100; i++) XX{Y'a2[i]YzYwY}[100]; XX}Z XXY{Version 1: access 2D YT. XXZvar s1YzY-.YcNew(); XXZY|Z (YsiYz0; i < _max; i++) XX{Y'Yo(YsaYz0; a < 100; a++)Y'{Y'XYo(YsxYz0; x < 100; x++)Y'X{Y'XXYscYza1[a, x];Y'X}Y'} XX} XXs1Y1;Z XXY{Version 2: access jagged YT. XXZvar s2YzY-.YcNew(); XXZY|Z (YsiYz0; i < _max; i++) XX{Y'Yo(YsaYz0; a < 100; a++)Y'{Y'XYo(YsxYz0; x < 100; x++)Y'X{Y'XXYscYza2[a][x];Y'X}Y'} XX} XXs2Y1;Z XXY{Results. XXZY%s1.Y"); XXY%s2.Y"); X} } ZResultsZ 2D YT access:X Z1286.5545 msZ Jagged YT access: Z 486.7875 msZ YPYO; Y! YDY; { Xconst Ys_maxYz100000; XY$X{Z XXY{Version 1: cY` 2D YT. XXZvar s1YzY-.YcNew(); XXYo(YsiYz0; i < _max; i++) XX{Y'ZCY`2DYUZ(); XX} XXs1Y1;Z XXY{Version 2: cY` jagged YT. XXZvar s2YzY-.YcNew(); XXYo(YsiYz0; i < _max; i++) XX{Y'ZCY`JaggedYUZ(); XX} XXs2Y1;Z XXY{PrYstimes. XXZY%s1.Y"); XXY%s2.Y"); X} XYAY}[][] ZCY`JaggedYUZ() X{ XXvar YTYzYwY}[100][]; XXYo(YsiYz0; i < 100; i++) XX{Y'YT[i]YzYwY}[100]; XX} XXYJ YT; X} XYAY}[,] ZCY`2DYUZ() X{ XXvar YTYzYwY}[100, 100]; XXYJ YT; X} } ZResultsZ 2D YT allocation:X Z202.1575 msZ Jagged YT allocation: Z452.0066 msZ YPYOYSYDY; { XY$X{ XXlong b1YzGC.GetTotalMemory(true);Z XX// XXY{This program tests the memory usage of a 1000 x 100 Y6 jagged YT. XX// XXZY}[][] jaggedYzYwY}[1000][]; XXYo(YsiYz0; i < 1000; i++) XX{Y'jagged[i]YzYwY}[100]; XX} XXlong b2YzGC.GetTotalMemory(true); XXjagged[0][0]Yz0; XXY%Z"{0} bytes (jagged 1000 x 100)"Z, b2 - b1); X} } Z 416028 bytes (jagged 1000 x 100) Z YPYOYSYDY; { XY$X{ XXlong b1YzGC.GetTotalMemory(true);Z XX// XXY{This tests the memory usage of a 1000 x 100 Y6 two-dimensional YT. XX// XXZY}[,] YTYzYwY}[1000, 100]; XXlong b2YzGC.GetTotalMemory(true); XXYT[0, 0]Yz0; XXY%Z"{0} bytes (2D 1000 x 100)"Z, b2 - b1); X} } Z 400032 bytes (2D 1000 x 100)Z

]jagged arrays<benchmarks 2D, jagged arraysFbenchmarks 2D, jagged array allocation<measures jagged array memory8measures 2D array memory