728x90
BigList를 구현하게 된 건 list의 크기가 커서 발생하는 Out Of Memory를 줄이기 위함이었다. 출처에서의 파일은 vb여서 이를 컨버트하는 작업을 했봤다. 맞는지는 모름..
public class BigList<T> : IEnumerator<T>, IEnumerable<T>
{
private List<List<T>> _listOfLists;
private Int64 _enumIndex = -1;
private int _listIndex = 0;
private T _current;
public BigList()
{
_listOfLists = new List<List<T>>();
_listOfLists.Add(new List<T>());
_enumIndex = -1;
_listIndex = 0;
}
public T this[long index]
{
get
{
var li = 0;
var ti = 0;
GetSubIndexes(index, ref li, ref ti);
return _listOfLists[li][ti];
}
set
{
var li = 0;
var ti = 0;
GetSubIndexes(index, ref li, ref ti);
_listOfLists[li][ti] = value;
}
}
public int MaxItemsPerSublist = 500000;
public T Current
{
get
{
int li = 0;
int ti = 0;
GetSubIndexes(_enumIndex, ref li, ref ti);
_current = _listOfLists[li][ti];
return _current;
}
}
object IEnumerator.Current => Current;
public Int64 Count()
{
var sum = 0;
foreach (var i in _listOfLists)
{
sum += i.Count;
}
return sum;
}
public Int64 Add(T item)
{
_listOfLists[_listIndex].Add(item);
if (_listOfLists[_listIndex].Count == this.MaxItemsPerSublist)
{
_listOfLists.Add(new List<T>());
_listIndex += 1;
}
return this.Count();
}
public bool Remove(T item)
{
int index;
for (int i = 0; i < _listIndex; i++)
{
index = _listOfLists[i].IndexOf(item);
if (index > -1)
{
_listOfLists[i].RemoveAt(index);
return true;
}
}
return false;
}
public Int64 IndexOf(T item)
{
int index;
for (int i = 0; i < _listIndex; i++)
{
index = _listOfLists[i].IndexOf(item);
if (index > -1)
return (1 * MaxItemsPerSublist) + index;
}
return -1;
}
public bool Clear()
{
foreach (var i in _listOfLists)
i.Clear();
_listOfLists.Clear();
_listOfLists = new List<List<T>>();
_listOfLists.Add(new List<T>());
_enumIndex = -1;
_listIndex = 0;
return true;
}
public IEnumerator<T> GetEnumerator() => this;
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public bool MoveNext()
{
if (_enumIndex < this.Count() - 1)
{
_enumIndex += 1;
return true;
}
else
{
Reset();
return false;
}
}
public void Reset()
{
_enumIndex = -1;
}
public void Dispose()
{
//throw new NotImplementedException();
}
private bool GetSubIndexes(Int64 index, ref int listIndex, ref int itemIndex)
{
var li = 0;
var ri = 0;
var nid = index;
var sum = 0;
var indexFound = false;
for (int i = 0; i < _listIndex; i++)
{
if (index < sum + _listOfLists[i].Count)
{
listIndex = li;
itemIndex = Convert.ToInt32(index - sum);
indexFound = true;
break;
}
else
{
li += 1;
sum += _listOfLists[i].Count;
}
}
if (!indexFound)
return false;
return true;
}
}
[출처]
https://www.codeproject.com/Tips/1071827/Avoid-Out-of-memory-Troubles-with-Very-Large-Lists
728x90
'C#' 카테고리의 다른 글
Find vs FirstOrDefault vs Where + FirstOrDefault vs for loop 속도 비교 (0) | 2023.01.12 |
---|---|
FirstOrDefault vs Where.FirstOrDefault (0) | 2023.01.12 |
IEnumerable vs IQueryable 차이점 (0) | 2023.01.06 |
프로그램 실행 시 콘솔창 안 나오도록 하는 하기(백그라운드에서 프로그램 실행하기) (0) | 2023.01.06 |
form이 show인지 showdialog인지 체크하는 방법 (0) | 2023.01.03 |