Laden...

Sehr große Collection anlegen (Millionen bis Milliarden von Elementen)

Erstellt von VanKurt vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.434 Views
V
VanKurt Themenstarter:in
56 Beiträge seit 2006
vor 13 Jahren
Sehr große Collection anlegen (Millionen bis Milliarden von Elementen)

Hallo!
Ich hab da mal eine Frage zu den Collections von C#. Z.B. eine List kann ja maximal int.MaxValue (=32767) viele Elemente aufnehmen. Ist es mit C# auch möglich mehr Elemente zu verwalten?
Ich hätte da gerne was im long/ulong Bereich....

So lang der PC ja genug Speicher hat, sollte das möglich sein, oder?

Gruß,
Boris

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

So lang der PC ja genug Speicher hat, sollte das möglich sein, oder?

In der CLR des Frameworks gibt die fest gesetzte Maximalgröße von 2GB für 1 Objekt - unabhängig ob 32/64bit.

Mit einer LinkedList ließe sich das AFAIK umgehen.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

1.373 Beiträge seit 2004
vor 13 Jahren

int.MaxValue ist 2147483647, also 2,14 Milliarden.

A
69 Beiträge seit 2010
vor 13 Jahren

je nachdem und unabhängig vom speicher geht .net bei 8-16 millionen objekten in einer appdomain der saft aus.

V
VanKurt Themenstarter:in
56 Beiträge seit 2006
vor 13 Jahren

@VizOne:
Das wäre immernoch zu wenig 😉

Dann werde ich mir wohl mal was überlegen müssen...oder auf C++ umsteigen...hmmm

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo VanKurt,

in c++ ist der int-Bereich auch nicht größer.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo VizOne,

zum Thema int: Seit .NET 4 gibt es BigInt. Soweit ich weiß, kann man damit jede Zahl - egal wie groß diese ist - deklarieren.

zero_x

V
VanKurt Themenstarter:in
56 Beiträge seit 2006
vor 13 Jahren

In C++ gibt es aber doch keine Speicher/Objektbegrenzungen, oder?
Da müsste eine Linked-List ja dann wirklich beliebig anwachsen können...

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Da müsste eine Linked-List ja dann wirklich beliebig anwachsen können...

In .net wohl auch. Es werden ja nur die Verweise auf Vorgänger und Nachfolger gespeichert. Wie gesagt die 2GB-Begrenzung gilt für ein Objekt - es können also mehrere 2GB-Objekte (theoretisch) existieren.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

V
VanKurt Themenstarter:in
56 Beiträge seit 2006
vor 13 Jahren

Steht das nicht im Widerspruch zur Aussage von oben?

je nachdem und unabhängig vom speicher geht .net bei 8-16 millionen objekten in einer appdomain der saft aus.

1.361 Beiträge seit 2007
vor 13 Jahren

Hi VanKurt,

beachte bei der LinkedList, dass hier das Argument von Arithmetika (sofern es stimmt) für die Anzahl der LinkedList-Knoten greift:

je nachdem und unabhängig vom speicher geht .net bei 8-16 millionen objekten in einer appdomain der saft aus.

Ich würde an deiner Stelle eine blockweise arbeiten. Und nicht direkt mit einer LinkedList. Sondern eben eine Art List<List<T>>.
Hier ist mal eine rudimentäre Implementierung (ohne IList-Schnittstelle)

public class LongList<T> : IEnumerable<T>
{
	private List<List<T>> blocks;
	private static ulong maximumBlockLength = 1<<27;
	
	public LongList()
	{
		blocks = new List<List<T>>();
		ExtendBlocks();
	}
	
	public T this[ulong index]
	{
		get 
		{
			int blockNumber = (int)(index / maximumBlockLength);
			int offset = (int)(index % maximumBlockLength);
			return blocks[blockNumber][offset];
		}
		set
		{
			int blockNumber = (int)(index / maximumBlockLength);
			int offset = (int)(index % maximumBlockLength);
			blocks[blockNumber][offset] = value;
		}
	}
	
	private List<T> LastBlock
	{
		get {return blocks[blocks.Count-1];}
	}
	
	private ulong FreeSpaceInLastBlock()
	{
		return maximumBlockLength - (ulong)LastBlock.Count;
	}
	
	private void ExtendBlocks()
	{
		blocks.Add(new List<T>());
	}
	
	public void Add(T x)
	{
		if(FreeSpaceInLastBlock() == 0)
			ExtendBlocks();
		LastBlock.Add(x);
	}
	
	public void Clear()
	{
		blocks.Clear();
		ExtendBlocks();
	}
	
	System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
	{
		foreach(List<T> block in blocks)
		{
			foreach(T x in block)
			{
				yield return x;
			}
		}
	}	
	public IEnumerator<T> GetEnumerator()
	{
		foreach(List<T> block in blocks)
		{
			foreach(T x in block)
			{
				yield return x;
			}
		}
	}	
}

beste Grüße
zommi

A
69 Beiträge seit 2010
vor 13 Jahren

Zugegeben, meine letzten Tests beruhten noch auf .net 2.0.
Auf meinem aktuellen Rechner konnte ich immerhin 33 Millionen Objekte in die LinkedList einfügen. Da die linked List das hinzugefügte Objekt in ein eigenes Objekt wrapped, macht das also in etwa 66 Millionen Objekte im Speicher.

code:

        static void Main(string[] args)
        {
            LinkedList<SmallClass> ll = new LinkedList<SmallClass>();
            long l = 0;
            try
            {
                for (; l < long.MaxValue; l++)
                {

                    ll.AddLast(new SmallClass());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(l);
                Console.WriteLine(e.ToString());
            }
            

            Console.WriteLine("fertig");
            Console.ReadLine();
        }

        public class SmallClass
        {
            private static long l = 0;

            private long field = l++;
        }
1.373 Beiträge seit 2004
vor 13 Jahren

Mich würde allerdings schon interessieren, was das für eine Anwendung ist, die solche wahnwitzig großen Mengen an Objekten im Speicher hält.

V
VanKurt Themenstarter:in
56 Beiträge seit 2006
vor 13 Jahren

Es geht um einen Logic-Analyzer den ich gerade bastel. Wenn alles gut läuft soll er im 100MHz Takt Messwerte aufnehmen, die am PC aufgezeichnet, gespeichert und visualisiert werden sollen.

Da kommt dann schon einiges zusammen 😉
Im Worst case 10^8 byte pro Sekunde, die alle einzeln und mit Zeitstempel vershen in den Speicher sollen...

5.742 Beiträge seit 2007
vor 13 Jahren

Im Worst case 10^8 byte pro Sekunde

100MB/s?
Da gibt es dann evtl. schon Probleme, die Daten erst einmal in den RAM zu laden - USB etc. fallen da ja flach.

V
VanKurt Themenstarter:in
56 Beiträge seit 2006
vor 13 Jahren

Ja ich fürchte da wird es an allen Ecken und Enden Probleme geben 😉
Aber ist ja nur ein Hobby/Freizeitprojekt, da ist es nicht schlimme wenn ich die hochgesteckten Ziele nicht erreiche. Aber Versuch macht kluch, gell?

3.971 Beiträge seit 2006
vor 13 Jahren

Da ich mir absolut nicht vorstellen kann, dass du mehrere Milliarden Objekten gleichzeitig brauchst, bau dir lieber eine Liste auf Basis von MemoryMappedFiles oder mittels Datenbank als Speicher und halte nur so viele Objekte im Speicher wie du gerade brauchst. Alles andere wird hier und da zu schweren Problemen führen.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

A
69 Beiträge seit 2010
vor 13 Jahren

Eine Datenbank würde auch ich empfehlen. Das Anzeigen so vieler Daten ist ohnehin nicht empfehlenswert, da ein Mensch so viel nicht erfassen kann. Also musst du die Daten vorher Grupperien/Filtern/Sortieren und genau in sowas sind Datenbanken richtig gut.