Tôi đã được ấn tượng rằng trong NET đúc (không chuyển đổi) là rất rẻ và nhanh chóng. Tuy nhiên, điều này dường như không phải là trường hợp cho mảng. Tôi đang cố gắng để làm một diễn viên rất đơn giản ở đây, lấy một T1 [] và cast như T2 []. nơi T1: T2.Tại sao các mảng đúc (vectơ) lại chậm?
Có 3 cách để làm điều này và tôi gọi họ như sau ::
DropCasting: T2[] array2 = array;
CastClass: (T2[])array;
IsInst: array as T2[];
Và tôi tạo ra phương pháp để làm điều này, không may, C# dường như để tạo ra một số mã khá lạ tuỳ theo nếu điều này là chung chung hay không. (Nếu DropCasting chung của nó sử dụng toán tử castclass. Và trong cả hai trường hợp đều từ chối phát ra toán tử 'as' khi T1: T2.
Dù sao, tôi đã viết một số phương thức động và thử nghiệm nó với một số kết quả đáng ngạc nhiên (string [] => object []):.?
DropCast : 223ms
IsInst : 3648ms
CastClass: 3732ms
Dropcasting là nhanh hơn so với một trong các nhà khai thác dàn diễn viên ~ 18 lần Tại sao đúc quá chậm đối với mảng đối với đối tượng bình thường như chuỗi => đối tượng, sự khác biệt là ít hơn nhiều nghiêm trọng.
DropCast : 386ms
IsInst : 611ms
CastClass: 519ms
Mã điểm chuẩn bel ow:
class Program
{
static readonly String[] strings = Enumerable.Range(0, 10).Select(x => x.ToString()).ToArray();
static Func<string[], object[]> Dropcast = new Func<Func<string[], object[]>>(
() =>
{
var method = new DynamicMethod("DropCast", typeof(object[]), new[] { typeof(object), typeof(string[]) },true);
var ilgen = method.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_1);
ilgen.Emit(OpCodes.Ret);
return method.CreateDelegate(typeof(Func<string[], object[]>)) as Func<string[], object[]>;
})();
static Func<string[], object[]> CastClass = new Func<Func<string[], object[]>>(
() =>
{
var method = new DynamicMethod("CastClass", typeof(object[]), new[] { typeof(object), typeof(string[]) },true);
var ilgen = method.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_1);
ilgen.Emit(OpCodes.Castclass, typeof(object[]));
ilgen.Emit(OpCodes.Ret);
return method.CreateDelegate(typeof(Func<string[], object[]>)) as Func<string[], object[]>;
})();
static Func<string[], object[]> IsInst = new Func<Func<string[], object[]>>(
() =>
{
var method = new DynamicMethod("IsInst", typeof(object[]), new[] { typeof(object), typeof(string[]) },true);
var ilgen = method.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_1);
ilgen.Emit(OpCodes.Isinst, typeof(object[]));
ilgen.Emit(OpCodes.Ret);
return method.CreateDelegate(typeof(Func<string[], object[]>)) as Func<string[], object[]>;
})();
static Func<string[], object[]>[] Tests = new Func<string[], object[]>[]{
Dropcast,
IsInst,
CastClass
};
static void Main(string[] args)
{
int maxMethodLength = Tests.Select(x => GetMethodName(x.Method).Length).Max();
RunTests(1, false, maxMethodLength);
RunTests(100000000, true, maxMethodLength);
}
static string GetMethodName(MethodInfo method)
{
return method.IsGenericMethod ?
string.Format(@"{0}<{1}>", method.Name, string.Join<Type>(",", method.GetGenericArguments())) : method.Name;
}
static void RunTests(int count, bool displayResults, int maxLength)
{
foreach (var action in Tests)
{
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
action(strings);
}
sw.Stop();
if (displayResults)
{
Console.WriteLine("{0}: {1}ms", GetMethodName(action.Method).PadRight(maxLength),
((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
}
Chỉnh sửa trước khi bất kỳ ai yêu cầu lưu giữ đúng đối với những thứ như int [] -> uint [] mà thông số kỹ thuật clr sẽ được truyền mà không cần chuyển đổi.
Vấn đề là xoa bóp quyền IL.Trong một phương thức cực kỳ nhỏ như '() => strings as object [];' trình biên dịch sẽ thả phương thức 'as'. Việc tạo phương thức động chỉ chạy một lần tại '.cctor' của chương trình. Sau đó mỗi phương pháp chỉ là đốm màu IL. Ngoài ra tôi đã thêm một "thể hiện" cho mỗi phương thức động (tham số đối tượng), chỉ để tránh sự lộn xộn khi sử dụng một ủy nhiệm trên một phương thức tĩnh. –
vâng, tôi đã bỏ lỡ lớp thứ hai của func khi đọc lần đầu tiên. Vì vậy, tôi đã xóa nhận xét của mình. ;) –
Đã bao gồm nhiều lần rồi, chỉ có thể tìm thấy trang chủ: http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two -array-covariance.aspx –