Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm have a large list of value types that needs to be given to OpenGL. It would be great if this could happen as quickly as possible. What I'm doing now looks like this:

List<Vertex> VList = new List<Vertex>();
... //Add vertices
Vertex[] VArray;
VList.CopyTo(VArray, VList.Length);
GL.SetData(..., VArray);

This list is easily 10MB big, so copying is slow. Can I do this without copying, like somehow get a pointer to the array used internally by List?

Or do I have to implement my own List class..

EDIT: I forgot to mention that I don't know the number of elements that will be added to the List.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
142 views
Welcome To Ask or Share your Answers For Others

1 Answer

If you need to access internal array repeatedly, it good practice to store accessor as delegate.

In this example, it's delegate to dynamic method. First call may not be fast, but subsequent calls (on List of same type) will be much faster.

public static class ListExtensions
{
    static class ArrayAccessor<T>
    {
        public static Func<List<T>, T[]> Getter;

        static ArrayAccessor()
        {
            var dm = new DynamicMethod("get", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, typeof(T[]), new Type[] { typeof(List<T>) }, typeof(ArrayAccessor<T>), true);
            var il = dm.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0); // Load List<T> argument
            il.Emit(OpCodes.Ldfld, typeof(List<T>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance)); // Replace argument by field
            il.Emit(OpCodes.Ret); // Return field
            Getter = (Func<List<T>, T[]>)dm.CreateDelegate(typeof(Func<List<T>, T[]>));
        }
    }

    public static T[] GetInternalArray<T>(this List<T> list)
    {
        return ArrayAccessor<T>.Getter(list);
    }
}

Make sure to include:

using System.Reflection;
using System.Reflection.Emit;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...