ইন নোদা সময় v2, আমরা ন্যানোসেকেন্ড রেজল্যুশন থেকে সরানোর করছি। এর অর্থ আমরা আমাদের আগ্রহী এমন পুরো সময়ের প্রতিনিধিত্ব করতে আর 8-বাইট পূর্ণসংখ্যার ব্যবহার করতে পারি না That এটি আমাকে নোদা সময়ের (অনেক) স্ট্রাক্টের স্মৃতি ব্যবহারের তদন্ত করতে উত্সাহিত করেছিল, যার ফলে আমাকে নেতৃত্ব দিয়েছে has সিএলআর এর প্রান্তিককরণ সিদ্ধান্তে একটি সামান্য বিজোড়তা উদঘাটনের জন্য।
প্রথমত, আমি বুঝতে পারছি এই যে হয় একটি বাস্তবায়ন সিদ্ধান্ত, এবং যে ডিফল্ট আচরণ যে কোন সময়ে পরিবর্তন হতে পারে। আমি বুঝতে পারছি যে আমি করতে পারেন ব্যবহার করে এটি পরিবর্তন [StructLayout]এবং [FieldOffset], কিন্তু আমি বরং একটি সমাধান যা প্রয়োজন হয়নি সম্ভব হলে সঙ্গে আসা পর্যন্ত চাই।
আমার মূল দৃশ্যটি হ'ল আমার কাছে structএমন একটি রয়েছে যা একটি রেফারেন্স-টাইপ ফিল্ড এবং অন্য দুটি মান-ধরণের ক্ষেত্র রয়েছে, যেখানে those ক্ষেত্রগুলির জন্য সহজ মোড়ক int। আমি আশা করেছিলাম যে that৪-বিট সিএলআরতে (রেফারেন্সের জন্য ৮ এবং অন্য প্রত্যেকের জন্য 4) 16 বাইট হিসাবে প্রতিনিধিত্ব করা হবে, তবে কোনও কারণে এটি 24 বাইট ব্যবহার করছে। আমি অ্যারে ব্যবহার করে স্থানটি পরিমাপ করছি, যাইহোক - আমি বুঝতে পারি যে বিভিন্ন পরিস্থিতিতে লেআউটটি ভিন্ন হতে পারে তবে এটি একটি যুক্তিসঙ্গত প্রারম্ভিক বিন্দুর মতো অনুভূত হয়েছিল।
সমস্যাটি দেখানোর জন্য এখানে একটি নমুনা প্রোগ্রাম রয়েছে:
using System;
using System.Runtime.InteropServices;
#pragma warning disable 0169
struct Int32Wrapper
{
int x;
}
struct TwoInt32s
{
int x, y;
}
struct TwoInt32Wrappers
{
Int32Wrapper x, y;
}
struct RefAndTwoInt32s
{
string text;
int x, y;
}
struct RefAndTwoInt32Wrappers
{
string text;
Int32Wrapper x, y;
}
class Test
{
static void Main()
{
Console.WriteLine("Environment: CLR {0} on {1} ({2})",
Environment.Version,
Environment.OSVersion,
Environment.Is64BitProcess ? "64 bit" : "32 bit");
ShowSize<Int32Wrapper>();
ShowSize<TwoInt32s>();
ShowSize<TwoInt32Wrappers>();
ShowSize<RefAndTwoInt32s>();
ShowSize<RefAndTwoInt32Wrappers>();
}
static void ShowSize<T>()
{
long before = GC.GetTotalMemory(true);
T[] array = new T[100000];
long after = GC.GetTotalMemory(true);
Console.WriteLine("{0}: {1}", typeof(T),
(after - before) / array.Length);
}
}
এবং আমার ল্যাপটপে সংকলন এবং আউটপুট:
c:\Users\Jon\Test>csc /debug- /o+ ShowMemory.cs
Microsoft (R) Visual C# Compiler version 12.0.30501.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.
c:\Users\Jon\Test>ShowMemory.exe
Environment: CLR 4.0.30319.34014 on Microsoft Windows NT 6.2.9200.0 (64 bit)
Int32Wrapper: 4
TwoInt32s: 8
TwoInt32Wrappers: 8
RefAndTwoInt32s: 16
RefAndTwoInt32Wrappers: 24
তাই:
- আপনার যদি কোনও রেফারেন্স টাইপ ক্ষেত্র না থাকে, সিএলআর
Int32Wrapperএকসাথে ক্ষেত্রগুলি প্যাক করতে খুশি (TwoInt32Wrappers8 এর আকার রয়েছে) - এমনকি একটি রেফারেন্স ধরণের ক্ষেত্র সহ, সিএলআর এখনও
intক্ষেত্রগুলি একসাথে প্যাক করতে খুশি (RefAndTwoInt32s16 এর আকার রয়েছে) - দুটির সংমিশ্রণে প্রতিটি
Int32Wrapperক্ষেত্র প্যাডড / 8 বাইটে সারিবদ্ধ বলে মনে হচ্ছে। (RefAndTwoInt32Wrappersআকার 24 আছে।) - ডিবাগারে একই কোডটি চালানো (তবে এখনও একটি রিলিজ বিল্ড) 12 এর আকার দেখায়।
আরও কয়েকটি পরীক্ষা-নিরীক্ষার অনুরূপ ফলাফল পাওয়া গেছে:
- মান ধরণের ক্ষেত্রগুলির পরে রেফারেন্স প্রকারের ক্ষেত্র স্থাপন করা কোনও লাভ করে না
objectপরিবর্তে ব্যবহার করাstringসাহায্য করে না (আমি এটি "কোনও রেফারেন্স টাইপ" আশা করি)- রেফারেন্সের চারপাশে "র্যাপার" হিসাবে অন্য কাঠামো ব্যবহার করা কোনও লাভ করে না
- জেনেরিক স্ট্রাক্টটি রেফারেন্সের চারপাশে মোড়ক হিসাবে ব্যবহার করা সাহায্য করে না
- যদি আমি ক্ষেত্রগুলি যোগ করতে থাকি (সরলতার জন্য জোড়ায়),
intক্ষেত্রগুলি এখনও 4 বাইট হিসাবেInt32Wrapperগণনা করে এবং ক্ষেত্রগুলি 8 বাইট হিসাবে গণনা করে [StructLayout(LayoutKind.Sequential, Pack = 4)]প্রতিটি কাঠামোর দৃষ্টিতে যুক্ত করা ফলাফলগুলি পরিবর্তন করে না
এর জন্য (আদর্শভাবে রেফারেন্স ডকুমেন্টেশনের সাহায্যে) কারও কাছে কোনও ব্যাখ্যা আছে বা আমি কীভাবে সিএলআরকে ইঙ্গিত পেতে পারি যে আমি ধ্রুবক ফিল্ড অফসেট উল্লেখ না করে ক্ষেত্রগুলি প্যাক করতে চাই ?
TwoInt32Wrappersবা একটি Int64এবং একটি দিয়ে একটি কাঠামো তৈরি করেন তবে কী হবে TwoInt32Wrappers? আপনি যদি জেনেরিক Pair<T1,T2> {public T1 f1; public T2 f2;}তৈরি করেন Pair<string,Pair<int,int>>এবং তারপরে তৈরি করেন এবং Pair<string,Pair<Int32Wrapper,Int32Wrapper>>কীভাবে? কোন সংমিশ্রণগুলি JITter কে জিনিসগুলি প্যাড করতে বাধ্য করে?
Pair<string, TwoInt32Wrappers> নেই যাতে সমস্যার সমাধান হবে মাত্র 16 বাইট দিতে। আকর্ষনীয়।
Marshal.SizeOfনেটিক কোডে কাঠামোর আকারের সাথে কোনও সম্পর্ক থাকার দরকার নেই এমন কাঠামোর আকারটি দেশীয় কোডে পাঠানো হবে।
Ref<T>তবেstringপরিবর্তে ব্যবহার করছেন, এটির কোনও পার্থক্য হওয়া উচিত নয়।