টিএল; ডিআর - তারা আইএল স্তরের সমতুল্য উদাহরণ examples
ডটনেটফিটাল উত্তরটি সুন্দর করে তোলে কারণ এটি আপনাকে ফলস্বরূপ আইএল দেখতে দেয়।
আমার পরীক্ষাটি আরও ত্বরান্বিত করার জন্য আমি আপনার লুপ কনস্ট্রাক্টের কিছুটা আলাদা প্রকরণ ব্যবহার করেছি। আমি ব্যবহার করতাম:
প্রকরণ 1:
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
int x;
int i;
for(x=0; x<=2; x++)
{
i = x;
Console.WriteLine(i);
}
}
}
পার্থক্য 2:
Console.WriteLine("Hello World");
int x;
for(x=0; x<=2; x++)
{
int i = x;
Console.WriteLine(i);
}
উভয় ক্ষেত্রেই সংকলিত আইএল আউটপুট একই রেন্ডার করেছে।
.class public auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method public hidebysig static void Main() cil managed
{
//
.maxstack 2
.locals init (int32 V_0,
int32 V_1,
bool V_2)
IL_0000: nop
IL_0001: ldstr "Hello World"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ldc.i4.0
IL_000d: stloc.0
IL_000e: br.s IL_001f
IL_0010: nop
IL_0011: ldloc.0
IL_0012: stloc.1
IL_0013: ldloc.1
IL_0014: call void [mscorlib]System.Console::WriteLine(int32)
IL_0019: nop
IL_001a: nop
IL_001b: ldloc.0
IL_001c: ldc.i4.1
IL_001d: add
IL_001e: stloc.0
IL_001f: ldloc.0
IL_0020: ldc.i4.2
IL_0021: cgt
IL_0023: ldc.i4.0
IL_0024: ceq
IL_0026: stloc.2
IL_0027: ldloc.2
IL_0028: brtrue.s IL_0010
IL_002a: ret
} // end of method Program::Main
সুতরাং আপনার প্রশ্নের উত্তর দেওয়ার জন্য: সংকলকটি ভেরিয়েবলের ঘোষণাকে অনুকূল করে এবং দুটি প্রকরণকে সমতুল্য উপস্থাপন করে।
আমার বোঝার জন্য,। নেট আইএল সংকলকটি ফাংশনের শুরুতে সমস্ত পরিবর্তনশীল ঘোষণাগুলি সরিয়ে নিয়েছে তবে আমি একটি ভাল উত্স খুঁজে পাইনি যা স্পষ্টভাবে বলেছিল যে 2 । এই বিশেষ উদাহরণে, আপনি দেখতে পাচ্ছেন যে এটি তাদের এই বিবৃতিটি দিয়ে সরিয়ে নিয়েছে:
.locals init (int32 V_0,
int32 V_1,
bool V_2)
এর সাথে আমরা তুলনা তৈরিতে কিছুটা বেশি আবেগপ্রবণ হই ....
কেস এ, সমস্ত ভেরিয়েবলগুলি সরানো হবে?
এটি আরও কিছুটা খনন করতে, আমি নিম্নলিখিত ফাংশনটি পরীক্ষা করেছি:
public static void Main()
{
Console.WriteLine("Hello World");
int x=5;
if (x % 2==0)
{
int i = x;
Console.WriteLine(i);
}
else
{
string j = x.ToString();
Console.WriteLine(j);
}
}
এখানে পার্থক্যটি হ'ল আমরা তুলনার উপর ভিত্তি করে একটি int i
বা একটি ঘোষণা করি string j
। আবার, সংকলকটি সমস্ত স্থানীয় ভেরিয়েবলগুলি সাথে ফাংশন 2 এর শীর্ষে নিয়ে যায় :
.locals init (int32 V_0,
int32 V_1,
string V_2,
bool V_3)
আমি এটি আকর্ষণীয় মনে করেছি যে int i
এই উদাহরণে ঘোষিত না হলেও এটি সমর্থন করার কোডটি এখনও উত্পন্ন হয়েছে।
কেস বি: foreach
পরিবর্তে কী হবে for
?
এটি চিহ্নিত করা হয়েছিল যে foreach
এর চেয়ে আলাদা আচরণ রয়েছে for
এবং যে বিষয়ে জিজ্ঞাসা করা হয়েছিল আমি সেই একই জিনিসটি যাচাই করছিলাম না। সুতরাং আমি ফলাফলের আইএল তুলনা করতে কোডের এই দুটি বিভাগে রেখেছি।
int
লুপের বাইরে ঘোষণা:
Console.WriteLine("Hello World");
List<int> things = new List<int>(){1, 2, 3, 4, 5};
int i;
foreach(var thing in things)
{
i = thing;
Console.WriteLine(i);
}
int
লুপের ভিতরে ঘোষণা:
Console.WriteLine("Hello World");
List<int> things = new List<int>(){1, 2, 3, 4, 5};
foreach(var thing in things)
{
int i = thing;
Console.WriteLine(i);
}
foreach
লুপের সাথে ফলাফল প্রাপ্ত আইএল লুপটি ব্যবহার করে উত্পন্ন আইএল থেকে প্রকৃতপক্ষে পৃথক ছিল for
। বিশেষত, আর ডি ব্লক এবং লুপ বিভাগটি পরিবর্তিত হয়েছে।
.locals init (class [mscorlib]System.Collections.Generic.List`1<int32> V_0,
int32 V_1,
int32 V_2,
class [mscorlib]System.Collections.Generic.List`1<int32> V_3,
valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32> V_4,
bool V_5)
...
.try
{
IL_0045: br.s IL_005a
IL_0047: ldloca.s V_4
IL_0049: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::get_Current()
IL_004e: stloc.1
IL_004f: nop
IL_0050: ldloc.1
IL_0051: stloc.2
IL_0052: ldloc.2
IL_0053: call void [mscorlib]System.Console::WriteLine(int32)
IL_0058: nop
IL_0059: nop
IL_005a: ldloca.s V_4
IL_005c: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
IL_0061: stloc.s V_5
IL_0063: ldloc.s V_5
IL_0065: brtrue.s IL_0047
IL_0067: leave.s IL_0078
} // end .try
finally
{
IL_0069: ldloca.s V_4
IL_006b: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
IL_0071: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0076: nop
IL_0077: endfinally
} // end handler
foreach
পদ্ধতির আরো স্থানীয় ভেরিয়েবল তৈরি এবং কিছু অতিরিক্ত শাখাবিন্যাস প্রয়োজন। মূলত, এটির প্রথমবারের মধ্যে অঙ্কের প্রথম পুনরাবৃত্তি পেতে লুপের শেষের দিকে লাফ দেয় এবং তারপরে লুপ কোডটি কার্যকর করতে লুপের প্রায় শীর্ষে ফিরে যায়। এটি তখন আপনার প্রত্যাশা মতো লুপ অবিরত থাকবে।
কিন্তু ব্যবহার দ্বারা সৃষ্ট শাখাবিন্যাস পার্থক্য পরলোক for
এবং foreach
নির্মান, ছিল কোন যেখানে উপর ভিত্তি করে আইএল পার্থক্য int i
ঘোষণা স্থাপন করা হয়েছিল। সুতরাং আমরা এখনও সমান দুটি পদ্ধতির এ।
কেস সি: বিভিন্ন সংকলক সংস্করণ সম্পর্কে কি?
একটি মন্তব্য বাম ছিল 1 , একটি একটি লিঙ্ক ছিল foreach এবং অবসান ব্যবহার করে পরিবর্তনশীল অ্যাক্সেস নিয়ে একটি সতর্কবার্তা সংক্রান্ত তাই প্রশ্ন । সেই প্রশ্নটিতে সত্যই যে অংশটি আমার নজর কেড়েছিল তা হ'ল নেট নেট .২.২ সংকলকটি সংকলকের পূর্ববর্তী সংস্করণগুলির বিপরীতে কীভাবে কাজ করেছিল।
এবং সেখানেই ডটনেটফিডলার সাইটটি আমাকে হতাশ করল - তাদের কাছে যা কিছু ছিল সেগুলি ছিল নেট .৪.৪ এবং রোজলিন সংকলকের একটি সংস্করণ। তাই আমি ভিজ্যুয়াল স্টুডিওর স্থানীয় উদাহরণ এনেছি এবং কোডটি পরীক্ষা করতে শুরু করেছি। আমি একই জিনিসগুলির সাথে তুলনা করছি কিনা তা নিশ্চিত করতে, আমি স্থানীয়ভাবে তৈরি কোডটি .NET 4.5 এ ডটনেটফিডলার কোডের সাথে তুলনা করেছি।
আমি যে পার্থক্যটি উল্লেখ করেছি তা হল স্থানীয় আরম্ভ ব্লক এবং পরিবর্তনশীল ঘোষণার সাথে। স্থানীয় সংকলকটি ভেরিয়েবলগুলির নামকরণে কিছুটা সুনির্দিষ্ট ছিল।
.locals init ([0] class [mscorlib]System.Collections.Generic.List`1<int32> things,
[1] int32 thing,
[2] int32 i,
[3] class [mscorlib]System.Collections.Generic.List`1<int32> '<>g__initLocal0',
[4] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32> CS$5$0000,
[5] bool CS$4$0001)
তবে সেই সামান্যতম পার্থক্যের সাথে, এটি এতদূর, এত ভাল ছিল। আমার ডটনেটফিডলার সংকলক এবং আমার স্থানীয় ভিএস উদাহরণটি যা উত্পাদন করছে তার মধ্যে আমার সমতুল্য আইএল আউটপুট ছিল।
সুতরাং আমি তখন প্রকল্পটি .NET 4, .NET 3.5, এবং ভাল পরিমাপের জন্য পুনরায় তৈরি করেছি N
এবং এই অতিরিক্ত ক্ষেত্রে তিনটি ক্ষেত্রেই উত্পন্ন আইএল সমান ছিল। এই নমুনাগুলিতে উত্পাদিত আইএলটিতে লক্ষ্যযুক্ত .NET সংস্করণটির কোনও প্রভাব ছিল না।
এই দু: সাহসিক কাজটির সংক্ষিপ্তসার হিসাবে: আমি মনে করি আমরা আত্মবিশ্বাসের সাথে বলতে পারি যে সংকলকটি আপনি কোথায় আদিম ধরণের ঘোষণা করেন তা যত্ন করে না এবং ঘোষণাপদ্ধতির কোনও পদ্ধতিতে স্মৃতি বা সম্পাদনের উপর কোনও প্রভাব পড়ে না। এবং যে একটি ব্যবহার নির্বিশেষে সত্য for
বা foreach
লুপ।
আমি foreach
লুপের অভ্যন্তরে একটি বন্ধকে অন্তর্ভুক্ত করে এমন আরও একটি মামলা চালানোর বিষয়টি বিবেচনা করেছি । তবে আপনি যেখানে আদিম ধরণের পরিবর্তনশীল ঘোষণা করা হয়েছিল তার প্রভাব সম্পর্কে জিজ্ঞাসা করেছিলেন, তাই আমি বুঝতে পেরেছিলাম যে আপনি যে বিষয়ে জিজ্ঞাসা করতে আগ্রহী তা থেকে আমি অনেক দূরে আগ্রহী। আমি ইতিপূর্বে উল্লিখিত এসও প্রশ্নটির একটি দুর্দান্ত উত্তর রয়েছে যা পূর্বাবর্তন পুনরাবৃত্তকরণ ভেরিয়েবলগুলিতে ক্লোজার ইফেক্ট সম্পর্কে একটি ভাল ওভারভিউ সরবরাহ করে।
1 লুপগুলির মধ্যে foreach
সমাপনীকরণের এসও প্রশ্নের মূল লিঙ্ক সরবরাহ করার জন্য অ্যান্ডিকে আপনাকে ধন্যবাদ ।
2 এটি লক্ষণীয় যে ইসিএমএ -৩৩৫ স্পেস এটিকে I.12.3.2.2 বিভাগ 'স্থানীয় ভেরিয়েবল এবং আর্গুমেন্ট' দিয়ে সম্বোধন করে। আমাকে ফলস্বরূপ আইএলটি দেখতে হয়েছিল এবং তারপরে এটি কী চলছে তা সম্পর্কে পরিষ্কার হওয়ার জন্য বিভাগটি পড়তে হয়েছিল। আড্ডায় এটি নির্দেশ করার জন্য র্যাচেট ফ্রিককে ধন্যবাদ।