I would like to know the size of a dictionary item in bytes.How could I do that? Is there any predefined method? I saw a similar question being answered saying to get the difference using GC.TotalMemory method. But here I cannot Gc.KeepAlive the object. Please advice. The problem of calculating the difference before and after the usage of the dictionary is not possible as the total memory would not only include that dictionary's memory but also memory of several other threads.Please provide an alternative way for this.
You can do like this :
long StopBytes = 0;
// Declare your dictionnary
Dictionary<string, int> myDictionary;
// Get total memory before create your dictionnary
long StartBytes = System.GC.GetTotalMemory(true);
// Initialize your dictionnary
myDictionary = new Dictionary<string, int>();
// Get total memory after create your dictionnary
StopBytes = System.GC.GetTotalMemory(true);
// This ensure a reference to object keeps object in memory
GC.KeepAlive(myFoo);
// Calcul the difference , and that all :-)
MessageBox.Show("Size is " + ((long)(StopBytes - StartBytes)).ToString());
More information here -> http://blogs.msdn.com/b/mab/archive/2006/04/24/582666.aspx
I have 2 object instances of same type. (To be precise this is Unity3D's AudioSource) I need to apply some action like initializing, destroying, etc to both, so I think storing them in an array would be a good idea so I can iterate.
AudioSource[] audioSources = new AudioSource[2];
With this I can foreach on the array and write initializing code and other common tasks only once.
But these two instances serves different purpose, say, the first is an AudioSource for BGM and the second is for SFX. This way the code will be more readable and I can still iterate over two instances by using the array.
So I think I should give an alternate names for each instance like bgmSource and sfxSource. I'd like to ask that is this the correct approach?
AudioSource bgmSource = audioSources[0];
AudioSource sfxSource = audioSources[1];
Another solution is using a Dictionary, its not very suitable for such small arrays
but it can help you distinct between objects without using second variable to store reference
to the one in the array.
For example:
Dictionary< string, AudioSource > audioSources;
audioSources = new Dictionary<string, AudioSource>
{
"BGM_SOURCE", new AudioSource(),
"SFX_SOURCE", new AudioSource()
};
Then you can also use enum for keeping track of dictionary keys instead of using string/constant values:
// Enum declaration
enum AudioSourceNames
{
BGM_SOURCE,
SFX_SOURCE
}
// Called before first update
public void Start()
{
// Dictionary declaration
Dictionary< int, AudioSource > audioSources;
audioSources = new Dictionary< int, AudioSource >
{
( int )BGM_SOURCE, new AudioSource(),
( int )SFX_SOURCE, new AudioSource()
};
// Accessing the dictionary
audioSources[ ( int )AudioSourceNames.BGM_SOURCE ].Play();
}
BTW: You can use the enumarator technique with array, this way you won't have to remember each AudioSource index in the array
From my point of view your solution seem good.
initializing code and other common tasks only once
The code for these things is hopefully in AudioSource, isn't it?
Well, it's legal. It's just a matter of preference/design. I would say that you could put them in a Dictionary of some sort. So you can properly label them through a key. That way you won't need to remember that [0] is bgmSource and [1] is sfxSource.
I have a list of objects and I'm doing a foreach on the list and I'm sending each object to a method that modifies the object and returns it; like this:
foreach (MyObjectModel o in TheMasterObject.ListOfMyObjectModel)
{
o = MyMethod(o);
}
That doesn't work. What I want to do is replace the object I'm iterating on with the modified version that gets returned by MyMethod.
What do I need to change?
Thanks.
You cannot reassign to the loop variable, and reassigning the variable wouldn't affect the object inside the list anyway. If you need to write over the object in a list, use a for loop.
for (int index = 0; index < list.Count; index++)
{
var obj = list[index];
list[index] = MyMethod(obj);
}
You cannot do it like this. C# does not allow modifying the iteration variable of the foreach. Your best option is to hold a secondary list and put the modified values in there and then replace the initial list. Alternatively, if your data structure allows direct indexing, you can replace the foreach with a for and then you will be able to assign the object directly.
If MyObjectModel is a class (not a struct) then you don't need to reassign it. A class is a reference type which means your method will get a pointer to the object in the collection. Any modifications you do in the method will be done on the actual object in the list. You don't need to replace it.
If it's a completely new object you are returning, then do what Anthony Pegram is suggesting.
for (int i =0; i < TheMasterObject.ListOfMyObjectModel.size(); ++i) {
TheMasterObject.ListOfMyObjectModel.set(i, MyMethod(TheMasterObject.ListOfMyObjectModel.get(i)));
}
I wrote this with java thinking, if some changes need to let it work on C#, be my guest
Use a for-loop instead of an iterator.
for (int i = 0; i < objectModels.Count; i++) {
objectModels[i] = MyMethod(objectModels[i]);
}
As for the why, this questions explains it:
Why is the iteration variable readonly
Hope this helps
Y
I have a possible implementation scenario where I need a dictionary object that will take 3 variables. A dialect, a query name and a query string. I should note at this stage that writing a separate class object is not an option.
My question is which of the following would perform better.
A) A single dictionary object that takes the first two variables in as a composite key e.g. "dialect,queryname" and the 3rd variable as the value.
private Dictionary<string, string>
B) A dictionary object that has another dictionary object as the value so the first variable would be the key of the primary dictionary object, the 2nd variable would be the key of the 2nd dictionary object and finally the 3rd variable would be the value of the second dictionary object.
private Dictionary<string, Dictionary<string, string>>
Seems obvious but the compiler is a mysterious thing so thought I should ask you guys.
Thanks
Just mucking around for my own amusement ..
Dictionary<string, string> md1 = new Dictionary<string,string>();
Dictionary<string, Dictionary<string, string>> md2 = new Dictionary<string, Dictionary<string, string>>();
Stopwatch st = new Stopwatch();
st.Start();
for (int i = 0; i < 2000000; i++)
{
md1.Add(i.ToString(), "blabla");
}
st.Stop();
Console.WriteLine(st.ElapsedMilliseconds);
st.Reset();
st.Start();
for (int i = 0; i < 2000000; i++)
{
md2.Add(i.ToString(), new Dictionary<string, string>());
}
st.Stop();
Console.WriteLine(st.ElapsedMilliseconds);
Console.ReadLine();
output:
831
1399
As long as you're sure that the key "dialect,queryname" is unique, I think the first solution is faster. In the second one, you'd have to do one more dictionary lookup, which is probably more costly than a string concatenation.
Why don't you use:
Dictionary<string, KeyValuePair<string, string>>
I think is better than both.
This is not a matter of performance, as the two have completely different semantics.
The first gives you a way to use one object to find another object.
The second gives you a way to use one object to find another object, in which you can use yet another object to find a third object.
There is slightly different functionality in terms of how these can be later extended.
Most generally, I'd use Dictionary<Tuple<string, string>, string>. This would give me a composite key that is clearly a composite key.
Actually, that's not true, I'd create a new class. How is that not an option? Still, if it was homework and "do not create a new class" was part of the question, I'd use Dictionary<Tuple<string, string>, string>.
Edit:
class DialectQuery : IEquatable<DialectQuery>
{
public Dialect{get;private set}
public Name{get;private set;}
public DialectQuery(string dialect, string name)
{
Dialect = dialect;
Name = name;
}
public bool Equals(DialectQuery other)
{
return other != null && Name == other.Name && Dialect == other.Dialect;
}
public override bool Equals(object other)
{
return Equals((object)other);
}
public override int GetHashCode()
{
int dHash = Dialect.GetHashCode();
return (dHash << 16 | dHash >> 16) ^ Name.GetHashCode();
}
}
So far it behaves exactly the same as Tuple. Now though if I get a change request that dialects must be case-insensitive but query names case-sensitive, or that dialects are codes and therefore require invariant comparison but names are human-input and therefore require culture-aware comparison, or anything else, I've got two simple changes to make.
YAGNI doesn't apply, it's not coding a massive object "in case you need it", it's defining a good "okay, I probably don't need it, but if I do it'll go here" point.
.NET offers a generic list container whose performance is almost identical (see Performance of Arrays vs. Lists question). However they are quite different in initialization.
Arrays are very easy to initialize with a default value, and by definition they already have certain size:
string[] Ar = new string[10];
Which allows one to safely assign random items, say:
Ar[5]="hello";
with list things are more tricky. I can see two ways of doing the same initialization, neither of which is what you would call elegant:
List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);
or
string[] Ar = new string[10];
List<string> L = new List<string>(Ar);
What would be a cleaner way?
EDIT: The answers so far refer to capacity, which is something else than pre-populating a list. For example, on a list just created with a capacity of 10, one cannot do L[2]="somevalue"
EDIT 2: People wonder why I want to use lists this way, as it is not the way they are intended to be used. I can see two reasons:
One could quite convincingly argue that lists are the "next generation" arrays, adding flexibility with almost no penalty. Therefore one should use them by default. I'm pointing out they might not be as easy to initialize.
What I'm currently writing is a base class offering default functionality as part of a bigger framework. In the default functionality I offer, the size of the List is known in advanced and therefore I could have used an array. However, I want to offer any base class the chance to dynamically extend it and therefore I opt for a list.
List<string> L = new List<string> ( new string[10] );
I can't say I need this very often - could you give more details as to why you want this? I'd probably put it as a static method in a helper class:
public static class Lists
{
public static List<T> RepeatedDefault<T>(int count)
{
return Repeated(default(T), count);
}
public static List<T> Repeated<T>(T value, int count)
{
List<T> ret = new List<T>(count);
ret.AddRange(Enumerable.Repeat(value, count));
return ret;
}
}
You could use Enumerable.Repeat(default(T), count).ToList() but that would be inefficient due to buffer resizing.
Note that if T is a reference type, it will store count copies of the reference passed for the value parameter - so they will all refer to the same object. That may or may not be what you want, depending on your use case.
EDIT: As noted in comments, you could make Repeated use a loop to populate the list if you wanted to. That would be slightly faster too. Personally I find the code using Repeat more descriptive, and suspect that in the real world the performance difference would be irrelevant, but your mileage may vary.
Use the constructor which takes an int ("capacity") as an argument:
List<string> = new List<string>(10);
EDIT: I should add that I agree with Frederik. You are using the List in a way that goes against the entire reasoning behind using it in the first place.
EDIT2:
EDIT 2: What I'm currently writing is a base class offering default functionality as part of a bigger framework. In the default functionality I offer, the size of the List is known in advanced and therefore I could have used an array. However, I want to offer any base class the chance to dynamically extend it and therefore I opt for a list.
Why would anyone need to know the size of a List with all null values? If there are no real values in the list, I would expect the length to be 0. Anyhow, the fact that this is cludgy demonstrates that it is going against the intended use of the class.
Create an array with the number of items you want first and then convert the array in to a List.
int[] fakeArray = new int[10];
List<int> list = fakeArray.ToList();
If you want to initialize the list with N elements of some fixed value:
public List<T> InitList<T>(int count, T initValue)
{
return Enumerable.Repeat(initValue, count).ToList();
}
Why are you using a List if you want to initialize it with a fixed value ?
I can understand that -for the sake of performance- you want to give it an initial capacity, but isn't one of the advantages of a list over a regular array that it can grow when needed ?
When you do this:
List<int> = new List<int>(100);
You create a list whose capacity is 100 integers. This means that your List won't need to 'grow' until you add the 101th item.
The underlying array of the list will be initialized with a length of 100.
This is an old question, but I have two solutions. One is fast and dirty reflection; the other is a solution that actually answers the question (set the size not the capacity) while still being performant, which none of the answers here do.
Reflection
This is quick and dirty, and should be pretty obvious what the code does. If you want to speed it up, cache the result of GetField, or create a DynamicMethod to do it:
public static void SetSize<T>(this List<T> l, int newSize) =>
l.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(l, newSize);
Obviously a lot of people will be hesitant to put such code into production.
ICollection<T>
This solution is based around the fact that the constructor List(IEnumerable<T> collection) optimizes for ICollection<T> and immediately adjusts the size to the correct amount, without iterating it. It then calls the collections CopyTo to do the copy.
The code for the List<T> constructor is as follows:
public List(IEnumerable<T> collection) {
....
ICollection<T> c = collection as ICollection<T>;
if (collection is ICollection<T> c)
{
int count = c.Count;
if (count == 0)
{
_items = s_emptyArray;
}
else {
_items = new T[count];
c.CopyTo(_items, 0);
_size = count;
}
}
So we can completely optimally pre-initialize the List to the correct size, without any extra copying.
How so? By creating an ICollection<T> object that does nothing other than return a Count. Specifically, we will not implement anything in CopyTo which is the only other function called.
private struct SizeCollection<T> : ICollection<T>
{
public SizeCollection(int size) =>
Count = size;
public void Add(T i){}
public void Clear(){}
public bool Contains(T i)=>true;
public void CopyTo(T[]a, int i){}
public bool Remove(T i)=>true;
public int Count {get;}
public bool IsReadOnly=>true;
public IEnumerator<T> GetEnumerator()=>null;
IEnumerator IEnumerable.GetEnumerator()=>null;
}
public List<T> InitializedList<T>(int size) =>
new List<T>(new SizeCollection<T>(size));
We could in theory do the same thing for AddRange/InsertRange for an existing array, which also accounts for ICollection<T>, but the code there creates a new array for the supposed items, then copies them in. In such case, it would be faster to just empty-loop Add:
public void SetSize<T>(this List<T> l, int size)
{
if(size < l.Count)
l.RemoveRange(size, l.Count - size);
else
for(size -= l.Count; size > 0; size--)
l.Add(default(T));
}
Initializing the contents of a list like that isn't really what lists are for. Lists are designed to hold objects. If you want to map particular numbers to particular objects, consider using a key-value pair structure like a hash table or dictionary instead of a list.
You seem to be emphasizing the need for a positional association with your data, so wouldn't an associative array be more fitting?
Dictionary<int, string> foo = new Dictionary<int, string>();
foo[2] = "string";
The accepted answer (the one with the green check mark) has an issue.
The problem:
var result = Lists.Repeated(new MyType(), sizeOfList);
// each item in the list references the same MyType() object
// if you edit item 1 in the list, you are also editing item 2 in the list
I recommend changing the line above to perform a copy of the object. There are many different articles about that:
String.MemberwiseClone() method called through reflection doesn't work, why?
https://code.msdn.microsoft.com/windowsdesktop/CSDeepCloneObject-8a53311e
If you want to initialize every item in your list with the default constructor, rather than NULL, then add the following method:
public static List<T> RepeatedDefaultInstance<T>(int count)
{
List<T> ret = new List<T>(count);
for (var i = 0; i < count; i++)
{
ret.Add((T)Activator.CreateInstance(typeof(T)));
}
return ret;
}
You can use Linq to cleverly initialize your list with a default value. (Similar to David B's answer.)
var defaultStrings = (new int[10]).Select(x => "my value").ToList();
Go one step farther and initialize each string with distinct values "string 1", "string 2", "string 3", etc:
int x = 1;
var numberedStrings = (new int[10]).Select(x => "string " + x++).ToList();
string [] temp = new string[] {"1","2","3"};
List<string> temp2 = temp.ToList();
After thinking again, I had found the non-reflection answer to the OP question, but Charlieface beat me to it. So I believe that the correct and complete answer is https://stackoverflow.com/a/65766955/4572240
My old answer:
If I understand correctly, you want the List<T> version of new T[size], without the overhead of adding values to it.
If you are not afraid the implementation of List<T> will change dramatically in the future (and in this case I believe the probability is close to 0), you can use reflection:
public static List<T> NewOfSize<T>(int size) {
var list = new List<T>(size);
var sizeField = list.GetType().GetField("_size",BindingFlags.Instance|BindingFlags.NonPublic);
sizeField.SetValue(list, size);
return list;
}
Note that this takes into account the default functionality of the underlying array to prefill with the default value of the item type. All int arrays will have values of 0 and all reference type arrays will have values of null. Also note that for a list of reference types, only the space for the pointer to each item is created.
If you, for some reason, decide on not using reflection, I would have liked to offer an option of AddRange with a generator method, but underneath List<T> just calls Insert a zillion times, which doesn't serve.
I would also like to point out that the Array class has a static method called ResizeArray, if you want to go the other way around and start from Array.
To end, I really hate when I ask a question and everybody points out that it's the wrong question. Maybe it is, and thanks for the info, but I would still like an answer, because you have no idea why I am asking it. That being said, if you want to create a framework that has an optimal use of resources, List<T> is a pretty inefficient class for anything than holding and adding stuff to the end of a collection.
A notice about IList:
MSDN IList Remarks:
"IList implementations fall into three categories: read-only, fixed-size, and variable-size. (...). For the generic version of this interface, see
System.Collections.Generic.IList<T>."
IList<T> does NOT inherits from IList (but List<T> does implement both IList<T> and IList), but is always variable-size.
Since .NET 4.5, we have also IReadOnlyList<T> but AFAIK, there is no fixed-size generic List which would be what you are looking for.
This is a sample I used for my unit test. I created a list of class object. Then I used forloop to add 'X' number of objects that I am expecting from the service.
This way you can add/initialize a List for any given size.
public void TestMethod1()
{
var expected = new List<DotaViewer.Interface.DotaHero>();
for (int i = 0; i < 22; i++)//You add empty initialization here
{
var temp = new DotaViewer.Interface.DotaHero();
expected.Add(temp);
}
var nw = new DotaHeroCsvService();
var items = nw.GetHero();
CollectionAssert.AreEqual(expected,items);
}
Hope I was of help to you guys.
A bit late but first solution you proposed seems far cleaner to me : you dont allocate memory twice.
Even List constrcutor needs to loop through array in order to copy it; it doesn't even know by advance there is only null elements inside.
1.
- allocate N
- loop N
Cost: 1 * allocate(N) + N * loop_iteration
2.
- allocate N
- allocate N + loop ()
Cost : 2 * allocate(N) + N * loop_iteration
However List's allocation an loops might be faster since List is a built-in class, but C# is jit-compiled sooo...