How to copy a list without using too much memory?

This appeared in a code review, and there was some disagreement on what to do. It includes a function that converts one type of array of objects to another.

The complaint was that you double the memory used for a short period of time, because the function is called many times. And at some point, both the temp observablecollection and observablecollection parameters that are assigned to the temp observablecollection variable will have data. So, right before the task is completed, the program memory will spike. There were also concerns that garbage collection would not be fast enough.

Many solutions have been proposed, but all of them are associated with a violation of the encapsulation of the method and a decrease in the simplicity of maintainability. Can anyone suggest an answer for this?

Edit: I see that many people point out that this is premature optimization. It also appeared in a code review. I think that for this example we could assume that this list would consume a huge amount of memory. The review boiled down to memory savings and reliable code maintenance. So, I think the real question is is there a solution that will make both camps happy?

Dramatically simplified code below:

public class ClassExample { public ObservableCollection<OriginalObjectType> OriginalObjectTypes { get; set; } public void ConvertNewObjectTypesToOriginal(ObservableCollection<ObjectType2> objectType2s) { ObservableCollection<OriginalObjectType> originalObjectTypesTemp = new ObservableCollection<OriginalObjectType>(); foreach (var objectType2 in objectType2s) { var originalObjectType = new OriginalObjectType { Value = objectType2.Value }; originalObjectTypesTemp.Add(originalObjectType); } this.OriginalObjectTypes = originalObjectTypesTemp; } } 
+6
source share
5 answers

Is there a reason to create a temporary collection in general?

 public class ClassExample { public ObservableCollection<OriginalObjectType> OriginalObjectTypes { get; set; } public void ConvertNewObjectTypesToOriginal(ObservableCollection<ObjectType2> objectType2s) { if (this.OriginalObjectTypes == null) this.OriginalObjectTypes = new ObservableCollection<OriginalObjectType>(); else this.OriginalObjectTypes.Clear(); foreach (var objectType2 in objectType2s) { var originalObjectType = new OriginalObjectType { Value = objectType2.Value }; this.OriginalObjectTypesTemp.Add(originalObjectType); } } } 
+2
source

Do you need a converter for your specific situation? Can you have your class implement an interface for each set of functions? Thus, you have a single instance of the object, but different views depending on your needs. This allows you to maintain a general view of the implementation, but to eliminate the problem with resources.

Update: In case you cannot use the interface, I agree with everyone else that you need to check how significant the problem really is. The garbage collector's memory graph should handle the subsequent burst of memory well, since it never completely frees the allocated memory space back to the OS. The only other option is to delete / convert / add each item individually, so that when you increase one list, the other list is reduced.

+3
source

Converting one type to another is usually not required. Can you just add the functionality of one class to another, either through a common interface or inheritance?

Something else if you just have to convert .. I have not tested this .. leave it up to you:

 class ClassOne { public ClassTwo ConvertToClassTwo() { // do conversion } } // usage: for (int64 index = 0; index < yourArray.Length; index++) { yourArray[index] = yourArray[index].ConvertToClassTwo(); } 
+1
source

The ability to keep memory consumption at a more or less constant level will be to use linked lists. You remove items from the first list by adding them to the second.

However, the linked list has overhead. A list of nodes is stored for each item. Therefore, it is doubtful whether this will be an improvement at all. If the objects in the first list are large compared to the nodes in the list, and if they can be garbage collected (if there is no other link to them), then yes, this may be an option.

I would not worry that the GC would be too slow. In any case, low memory will trigger garbage collection.

0
source

You could save a small amount of memory without using an ObservableCollection as an intermediary:

 public class ClassExample { public ObservableCollection<OriginalObjectType> OriginalObjectTypes { get; set; } public void ConvertNewObjectTypesToOriginal(ObservableCollection<ObjectType2> objectType2s) { this.OriginalObjectTypes = new ObservableCollection<OriginalObjectType>(new List<ObjectType2>(objectType2s).ConvertAll<OriginalObjectType>(new Converter<ObjectType2, OriginalObjectType>(ConvertOT2ToOOT))); } public static OriginalObjectType ConvertOT2ToOOT(ObjectType2 objectType2) { return new OriginalObjectType { Value = objectType2.Value }; } } 

In this case, List<T> , which may not help much, but comes with a convenient ConvertAll method.

0
source

Source: https://habr.com/ru/post/922505/


All Articles