Skip to content

Instantly share code, notes, and snippets.

@odinhaus
Created November 16, 2016 16:50
Show Gist options
  • Save odinhaus/8942b8e0455cf9e930d93414edc0ee47 to your computer and use it in GitHub Desktop.
Save odinhaus/8942b8e0455cf9e930d93414edc0ee47 to your computer and use it in GitHub Desktop.
Fast C# Byte[] Copier Using Cpblk IL Instruction
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Tests
{
public class FastCopy
{
static readonly ICopier _copier;
protected static AssemblyName _asmName = new AssemblyName() { Name = "FastCopier" };
protected static ModuleBuilder _modBuilder;
protected static AssemblyBuilder _asmBuilder;
static FastCopy()
{
_asmBuilder = Thread.GetDomain().DefineDynamicAssembly(_asmName, AssemblyBuilderAccess.RunAndSave);
_modBuilder = _asmBuilder.DefineDynamicModule(_asmName.Name, _asmName.Name + ".dll", true);
var typeBuilder = _modBuilder.DefineType("FastCopier",
TypeAttributes.Public
| TypeAttributes.AutoClass
| TypeAttributes.AnsiClass
| TypeAttributes.Class
| TypeAttributes.Serializable
| TypeAttributes.BeforeFieldInit);
typeBuilder.AddInterfaceImplementation(typeof(ICopier));
var copyMethod = typeBuilder.DefineMethod("Copy",
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
typeof(void),
new Type[] { typeof(byte[]), typeof(byte[]), typeof(int), typeof(uint) });
var code = copyMethod.GetILGenerator();
code.Emit(OpCodes.Ldarg_2);
code.Emit(OpCodes.Ldc_I4_0);
code.Emit(OpCodes.Ldelema, typeof(byte));
code.Emit(OpCodes.Ldarg_1);
code.Emit(OpCodes.Ldarg_3);
code.Emit(OpCodes.Ldelema, typeof(byte));
code.Emit(OpCodes.Ldarg, 4);
code.Emit(OpCodes.Cpblk);
code.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(copyMethod, typeof(ICopier).GetMethod("Copy"));
var copierType = typeBuilder.CreateType();
_copier = (ICopier)Activator.CreateInstance(copierType);
}
public static void Copy(byte[] source, byte[] dest, int offset, uint count)
{
_copier.Copy(source, dest, offset, count);
}
}
public interface ICopier
{
void Copy(byte[] source, byte[] dest, int offset, uint count);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment