Question about array subscripting in C# - c#

Back in the old days of C, one could use array subscripting to address storage in very useful ways. For example, one could declare an array as such.
This array represents an EEPROM image with 8 bit words.
BYTE eepromImage[1024] = { ... };
And later refer to that array as if it were really multi-dimensional storage
BYTE mpuImage[2][512] = eepromImage;
I'm sure I have the syntax wrong, but I hope you get the idea.
Anyway, this projected a two dimension image of what is really single dimensional storage.
The two dimensional projection represents the EEPROM image when loaded into the memory of an MPU with 16 bit words.
In C one could reference the storage multi-dimensionaly and change values and the changed values would show up in the real (single dimension) storage almost as if by magic.
Is it possible to do this same thing using C#?
Our current solution uses multiple arrays and event handlers to keep things synchronized. This kind of works but it is additional complexity that we would like to avoid if there is a better way.

You could wrap the array in a class and write 1-dimensional and 2-dimensional Indexer properties.
Without validations etc it looks like this for a 10x10 array:
class ArrayData
{
byte[] _data = new byte[100];
public byte this[int x]
{
get { return _data[x]; }
set { _data[x] = value; }
}
public byte this[int x, int y]
{
get { return _data[x*10+ y]; }
set { _data[x*10 + y] = value; }
}
}

Yes, but no.
You can allocate a multidimensional array off the bat if you like. You could also create a custom class that allows you to access its underlying data in either a single-dimension or multi-dimensional way, keeping the underlying data in sync.
You cannot, however, access a single-dimensional array with a multi-dimensional index directly.

Related

C# sort array of structs

I am running a simulation part of which requires sort of array of pairs of values.
When I used Array.Sort(v1,v2) it sorts 2 arrays based on first and all the simulation takes roughly 9 ms.
But I need to sort based on first then second so I created array of structs. See my code below.
private struct ValueWithWeight : IComparable<ValueWithWeight>
{
public double Value;
public double Weight;
public int CompareTo(ValueWithWeight other)
{
int cmp = this.Value.CompareTo(other.Value);
if (cmp != 0)
return cmp;
else
return this.Weight.CompareTo(other.Weight);
}
}
void Usage()
{
ValueWithWeight[] data = FillData();
Array.Sort(data);
}
Now it takes roughly 27ms. Is there any better way to sort ?
Since you're going to extremely optimize it please consider following:
Array.Sort runs over your array and performs comparison. In your case, there will not be unboxing since you implemented an interface on structure.
Array.Sort performs swap of elements while sorting. Swapping is internally memmove. Your structure takes at least 16 bytes. You can try to reduce impact by allocating your double values in class. Class will always occupy IntPtr.Size bytes (because you will store pointers) so it should copy less bytes.

Is equivalent the memory used by an array of ints vs an array of structs having just one int?

Considering the next struct...
struct Cell
{
int Value;
}
and the next matrix definitions
var MatrixOfInts = new int[1000,1000];
var MatrixOfCells = new Cell[1000,1000];
which one of the matrices will use less memory space? or are they equivalent (byte per byte)?
Both are the same size because structs are treated like any of the other value type and allocated in place in the heap.
long startMemorySize2 = GC.GetTotalMemory(true);
var MatrixOfCells = new Cell[1000, 1000];
long matrixOfCellSize = GC.GetTotalMemory(true);
long startMemorySize = GC.GetTotalMemory(true);
var MatrixOfInts = new int[1000, 1000];
long matrixOfIntSize = GC.GetTotalMemory(true);
Console.WriteLine("Int Matrix Size:{0}. Cell Matrix Size:{1}",
matrixOfIntSize - startMemorySize, matrixOfCellSize - startMemorySize2);
Here's some fun reading from Jeffery Richter on how arrays are allocated http://msdn.microsoft.com/en-us/magazine/cc301755.aspx
By using the sizeof operator in C# and executing the following code (under Mono 3.10.0) I get the following results:
struct Cell
{
int Value;
}
public static void Main(string[] args)
{
unsafe
{
// result is: 4
var intSize = sizeof(int);
// result is: 4
var structSize = sizeof(Cell);
}
}
So it looks like that an integer and a struct storing an integer consume the same amount of memory, I would therefore assume that arrays would also require an equal amount of memory.
In an array with value-type elements, all of the elements are required to be of the exact same type. The object holding the array needs to store information about the type of elements contained therein, but that information is only stored once per array, rather than once per element.
Note that because arrays receive special handling in the .NET Framework (compared to other collection types) arrays of a structure type will allow elements of the structures contained therein to be acted upon "in-place". As a consequence, if one can limit oneself to storing a structure within an array (rather than some other collection type) and can minimize unnecessary copying of struct instances, it is possible to operate efficiently with structures of almost any size. If one needs to hold a collection of things, each of which will have associated with it four Int64 values and four Int32 values (a total of 48 bytes), using an array of eight-element exposed-field structures may be more efficient and semantically cleaner than representing each thing using four elements from an Int64[] and four elements from an Int32[], or using an array of references to unshared mutable class objects.

Advantages of indexers over object array?

I read about indexers in MSDN - Indexers which explains how we can use objects like array with index i.e. just like normal Array. However, I think we can create array of objects like
point[] array = new point[100];
So what is the special advantages Indexer over object array?
If all you are after is a collection of objects then an indexer has absolutely no benefit over an array. However, if you need to store state as well as a collection, that's where an indexer shines.
For example, consider the following
public class Tree
{
private Branch[] branches = new Branch[100];
...
public string Name { get; set; }
public Branch this[int i]
{
get
{
return branches[i];
}
}
}
Tree holds an internal collection but also has state of it's own. Having an indexer property allows for simple access to the underlying collection e.g.
tree.Name = "Tree";
var branch = tree[0];
Not in this case that you have mentioned above. However, if you have anything that cannot be represented as an array will be a good example for Indexers to be used.
One .Net framework example is Dictionary. If you see the definition of Dictionary type in .Net you will find that they let you get an access of value through key. So that is a good example of using indexers where the index is presented as string.
Without indexers, how would you do that? of course by index value but it cannot be of type string then, will that be user friendly? I guess not!
So indexers gives you an opportunity to represent your code well.
Similarly, in case of point type, of course you can access the value of by index i.e. 0,1,2...99. What if you want to make more user friendly, such as point["x"]. That is where Indexers will help you.
Another example I could think of how about if you want to access your stack like s1 instead of push and s[0] instead of pop method.
There is a very good example of indexers by Microsoft where you can access file byte by byte by providing character location as index.
http://msdn.microsoft.com/en-us/library/aa288465(v=vs.71).aspx
In your line of code, you've defined an array of point objects, whatever those might be.
point[] array = new point[100];
Assuming you have direct access to the array, you can access the first element in your array like this:
var firstPoint = array[0];
The page you linked to is showing you how you could access that array, if it were defined inside your class, and you didn't have direct access to the array (since it's private).
For example, we could modify the example on that page to use your array:
class SampleCollection
{
private Point[] arr = new Point[100];
public Point this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
Then you could access the first element in the array like this:
var sc = new SampleCollection();
var item1 = sc[0];
That isn't an indexer.
An indexer is not used to create an array of objects, it is actually an operator overload to the '[]' operator.
An example for it's use would be if you wanted to make a List wrapper class.
In order to preserve the square braces functionality you would need (and want) to override the square braces operator. This is done via an indexer method.

Simulate a memory space in C#

I want to simulate a flash memory architecture in C#. More specifically the architecture looks like the following:
Flash memory is a collection of blocks
1 block = 128 sectors
a sector is composed of a data area and spare area
data area = 8 kB
spare area = 16 B
I wanted to represent this in a struct or in a class but the problem is I don't know how to represent a certain amount of memory space in the code. I can't use int or char arrays since I don't know what is to be stored in that memory space.... I am not very sure but I think I can represent it using byte datatype....
Yes, it sounds like you want a byte array. For example:
public sealed class Block
{
private readonly Sector[] sectors = new Sector[128];
public Sector this[int index] { get { return sectors[index]; } }
}
public sealed class Sector
{
private readonly byte[] data = new byte[8 * 1024];
public byte this[int index]
{
get { return data[index]; }
set { data[index] = value; }
}
}
(You can model the "spare" area as well if you want - it's not clear whether you really need to though.)
That's only allowing single-byte-at-a-time access - you may well want to have GetData and SetData methods on Block which read/write chunks of data at a time. Hopefully this will get you started though.

Deep copying reference types

I am using a class called BigNumDesc that represents a number. I have a jagged array of that numbers, that represent a matrix.
I first declare this matrix the following way:
BigNumDec[][] matrix = new BigNumDec[][] {
new BigNumDec[] { 1, 2 },
new BigNumDec[] { 3, 4 }
};
Now, I have this method I want to call:
static BigNumDec[][] GetStrictlyUpperTriangle(BigNumDec[][] matrix)
{
BigNumDec[][] newMatrix = new BigNumDec[matrix.Length][];
matrix.CopyTo(newMatrix, 0);
return null;
}
I have a break-point in the last line. If in the watch window, I take any item of matrix, and change it, it will change too newMatrix, as all BigNumDec are reference types(bad design decision from the creator of it?). How can I accomplish this? I need to make modifications to newMatrix, so I must copy it first from matrix.
edit: Tried the same now with ints, but it's happening just the same. I'd it wouldn't happen with value types?
BigNumDec is immutable.
The reason it's still happening with value types is because you're using an array of arrays. You're shallow-copying the "outer" array, which just copies the references to the two "inner" arrays.
You haven't shown whether BigNumDec is immutable or not (I would hope so) but if it is, you should be fine if you just deep copy the array. Alternatively, can you use a rectangular array [,] instead of a jagged array [][]? If so, a simple copy would suffice. There are performance implications with rectangular arrays, mind you - it's worth testing this to see whether it'll be a problem for you. You get better locality of reference, but the actual array access isn't as fast.
The issue is with your initialisation of the BigNumDec array, you are creating a 1-dimensional array of BigNumDec objects. [0] = { 1, 2 }, [1] = { 3. 4 }. You are then effectively copying the references those objects, not their content, hence why the values continue to change.
Change your initialisation to:
BigNumDec[,] matrix = new BigNumDec[,] {
{ 1, 2 },
{ 3, 4 }
};
If your objects are Serializable you can implement deep copy using serialization. It's not very efficient (by performance) but it's simple.
public BigNumDec[][] CopyUsingSerialization(BigNumDec[][] original)
{
var binaryFormatter = new BinaryFormatter();
var serializationStream = new MemoryStream();
binaryFormatter.Serialize(serializationStream, original);
serializationStream.Position = 0;
var copy = (BigNumDec[][])binaryFormatter.Deserialize(serializationStream);
return copy;
}
You have to declare the BigNumDec as [Serializable]:
[Serializable]
public class BigNumDec
{
//class content
}
(as said in other answers here, if you can move to two dimensional array instead of jagged you'll get better solution)

Categories