using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace ConsoleApplication2
{
public class CompactHeap<T>
: IDisposable where
T : new()
{
#region Fields
private
IntPtr _ptr, _currPtr;
private
int _rawSize;
private
Type _type;
private
T _t;
#endregion
public
CompactHeap(int num)
{
_t = new
T();
_type = _t.GetType();
_rawSize = Marshal.SizeOf(_t);
_ptr = Marshal.AllocHGlobal(_rawSize
* num);
_currPtr = _ptr;
}
public void Add(T t)
{
Marshal.StructureToPtr(t,
_ptr, false);
_ptr = new
IntPtr((_ptr.ToInt32() + _rawSize));
}
public
T Get(int index)
{
IntPtr
p = new IntPtr(_currPtr.ToInt32()
+ _rawSize * index);
return
(T)Marshal.PtrToStructure(p, _type);
}
public void Dispose()
{
Marshal.FreeHGlobal(_currPtr);
}
}
class Program
{
static void Main(string[]
args)
{
int
totalNum = 1000 * 10000;
using
(CompactHeap<Modes>
head = new CompactHeap<Modes>(totalNum))
{
Stopwatch
sw = new Stopwatch();
sw.Start();
for
(int t = 0; t < totalNum; t++)
{
Modes
m = new Modes();
m.UserHeap = t; m.UserID = t; head.Add(m);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds.ToString());
Modes
m500000 = head.Get(500000);
Console.WriteLine("m500000"+m500000.UserID);
Modes
m8 = head.Get(8);
Console.WriteLine("m8"+m8.UserID);
}
Console.ReadLine();
}
}
public struct Modes
{
public int UserID;
public int UserHeap;
}
}
//照到抄的,联想是,本来是因为在Vb 里面要传个VarPtr过去。不过弄到后面发现GC.Handle 的那个 IntPtr 好像不行吧。觉得这类型的应该是在Marshal 里面操作吧。毕竟这个是操作非托管堆的。So 真正要做的时候该杂做呢。Marshal.allochgolbal()建实例。不过感觉性能有限吧。但是觉得肯定可以传IntPtr.