প্লাস সাইন ব্যবহার করার সময় কতগুলি স্ট্রিং অবজেক্ট তৈরি করা হবে?


115

নীচের কোডটিতে প্লাস সাইন ব্যবহার করার সময় কতগুলি স্ট্রিং অবজেক্ট তৈরি করা হবে?

String result = "1" + "2" + "3" + "4";

এটি নীচের মতো থাকলে, আমি তিনটি স্ট্রিং অবজেক্ট: "1", "2", "12" বলতাম।

String result = "1" + "2";

আমি আরও জানি যে স্ট্রিং অবজেক্টগুলি পারফরম্যান্স উন্নতির জন্য স্ট্রিং ইন্টার্ন পুল / সারণিতে ক্যাশে করা হয়, তবে এটি প্রশ্ন নয়।


স্ট্রিংগুলি কেবল ইন্টার্ন করা হয় যদি আপনি স্পষ্টভাবে স্ট্রিং.ইন্টার্ন কল করেন।
জো হোয়াইট

7
@ জোওহাইট: তারা কি?
ইগোর কোরখভ

13
বেশ না। সমস্ত স্ট্রিং লিটারেলগুলি স্বয়ংক্রিয়ভাবে ইন্টার্ন করা হয়। স্ট্রিং অপারেশনের ফলাফল নয়।
স্টিফান পল নোক 18

আরও কী, ওপি উদাহরণে, কেবল একটি স্ট্রিং ধ্রুবক থাকে এবং এটি অভ্যন্তরীণ হয়। আমি আমার উত্তর আপডেট করতে।
ক্রিস শেইন

+1 টি। সেই স্টাইলে স্ট্রিং ক্যাটেনেশন কোডিং করার প্রয়োজনীয়তার বাস্তব জীবনের উদাহরণের জন্য, এমএসডিএন.মাইক্রোসফটকম / en - us / library/… এর উদাহরণ বিভাগে একটি রয়েছে যা সংকলক এটি অপ্টিমাইজ করতে না পারলে সম্ভব হত না বৈশিষ্ট্য পরামিতিগুলিতে নির্ধারিত মানগুলির প্রতিবন্ধকতার কারণে, একটি একক ধ্রুবকের কাছে।
ClickRick

উত্তর:


161

আশ্চর্যজনকভাবে, এটি নির্ভর করে।

আপনি যদি কোনও পদ্ধতিতে এটি করেন:

void Foo() {
    String one = "1";
    String two = "2";
    String result = one + two + "34";
    Console.Out.WriteLine(result);
}

তারপরে String.Concatসংকলকটি @ জোয়াচিম জবাব (+1 তার কাছে বিটিডাব্লু) হিসাবে কোডটি নির্গত করে বলে মনে হচ্ছে ।

যদি আপনি এগুলি স্থির হিসাবে সংজ্ঞায়িত করেন , যেমন:

const String one = "1";
const String two = "2";
const String result = one + two + "34";

বা আক্ষরিক হিসাবে, মূল প্রশ্নের মতো:

String result = "1" + "2" + "3" + "4";

তারপরে সংকলক সেই +চিহ্নগুলিকে অপ্টিমাইজ করবে । এটি এর সমতুল্য:

const String result = "1234";

তদ্ব্যতীত, সংকলক বহিরাগত ধ্রুবক অভিব্যক্তিগুলি সরিয়ে ফেলবে এবং কেবলমাত্র সেগুলি ব্যবহার বা প্রকাশিত হলে তা নির্গত করে। উদাহরণস্বরূপ, এই প্রোগ্রাম:

const String one = "1";
const String two = "1";
const String result = one + two + "34";

public static void main(string[] args) {
    Console.Out.WriteLine(result);
}

কেবল একটি স্ট্রিং তৈরি করে - ধ্রুবক result("1234" এর সমান)। oneএবং twoফলাফল আইএল প্রদর্শিত হবে না।

মনে রাখবেন রানটাইমে আরও অনুকূলিতকরণ হতে পারে। আমি শুধু আইএল উত্পাদন করে যাচ্ছি।

অবশেষে, ইন্টার্নিংয়ের ক্ষেত্রে, ধ্রুবক এবং আক্ষরিক ইন্টার্ন করা হয়, তবে যে মানটি অভ্যন্তরীণ হয় তা হ'ল আক্ষরিক নয়, আইএলে ফলস্বরূপ স্থির মান। এর অর্থ হ'ল আপনি প্রত্যাশার চেয়ে আরও কম স্ট্রিং অবজেক্ট পেতে পারেন, যেহেতু একাধিক অভিন্ন-সংজ্ঞায়িত ধ্রুবক বা আক্ষরিকাগুলি আসলে একই বস্তু হবে! এটি নিম্নলিখিত দ্বারা চিত্রিত:

public class Program
{
    private const String one = "1";
    private const String two = "2";
    private const String RESULT = one + two + "34";

    static String MakeIt()
    {
        return "1" + "2" + "3" + "4";
    }   

    static void Main(string[] args)
    {
        string result = "1" + "2" + "34";

        // Prints "True"
        Console.Out.WriteLine(Object.ReferenceEquals(result, MakeIt()));

        // Prints "True" also
        Console.Out.WriteLine(Object.ReferenceEquals(result, RESULT));
        Console.ReadKey();
    }
}

যে ক্ষেত্রে স্ট্রিংগুলি লুপে (বা অন্যথায় গতিশীলভাবে) সংমিশ্রিত হয়, আপনি প্রতিযোগিতা প্রতি এক অতিরিক্ত স্ট্রিং দিয়ে শেষ করেন। উদাহরণস্বরূপ, নিম্নলিখিতগুলি 12 টি স্ট্রিং দৃষ্টান্ত তৈরি করে: 2 টি ধ্রুবক + 10 পুনরাবৃত্তি, যার ফলে প্রতিটি নতুন স্ট্রিংয়ের উদাহরণ দেয়:

public class Program
{
    static void Main(string[] args)
    {
        string result = "";
        for (int i = 0; i < 10; i++)
            result += "a";
        Console.ReadKey();
    }
}

তবে (এছাড়াও আশ্চর্যরূপে), একাধিক পর পরের যুক্তিগুলি সংকলক দ্বারা একক একাধিক স্ট্রিং সংমিশ্রণে একত্রিত হয়। উদাহরণস্বরূপ, এই প্রোগ্রামটি কেবলমাত্র 12 টি স্ট্রিং উদাহরণ তৈরি করে! এটি কারণ " যদি আপনি এক বিবৃতিতে বেশ কয়েকটি + অপারেটর ব্যবহার করেন তবে স্ট্রিং সামগ্রীটি একবারে অনুলিপি করা হয়। "

public class Program
{
    static void Main(string[] args)
    {
        string result = "";
        for (int i = 0; i < 10; i++)
            result += "a" + result;
        Console.ReadKey();
    }
}

স্ট্রিং ফলাফল সম্পর্কে কী = "1" + "2" + তিন + চার; যেখানে দুটি এবং তিনটি স্ট্রিং থ্রি = "3" এর মতো ঘোষণা করা হয়; স্ট্রিং ফোর = "4" ;?
হালকা

এমনকি এক স্ট্রিং এর ফলাফল। আমি নিজেকে লম্বা পরীক্ষা করার জন্য লিনকপ্যাড দিয়ে এসেছি ran
ক্রিস শাইন

1
@ সার্ভে - মন্তব্যটি আপডেট হয়েছে বলে মনে হচ্ছে। আপনি যখন কোনও মন্তব্য পরিবর্তন করেন এটি পরিবর্তিত হিসাবে চিহ্নিত করা হয় না।
সুরক্ষা মাউন্ট

1
সম্পূর্ণরতার জন্য বিবেচনা করা ভাল যে একটি কেস লুপ মধ্যে সংক্ষিপ্ত হয়। উদাহরণস্বরূপ নীচের কোডটি কতগুলি স্ট্রিং অবজেক্ট বরাদ্দ করে:string s = ""; for (int i = 0; i < n; i++) s += "a";
জোরেেন

1
আমি ব্যবহার LINQPad ( linqpad.net ) অথবা প্রতিফলক ( reflector.net )। প্রাক্তনটি আপনাকে কোডের স্বেচ্ছাসেবক স্নিপেটের আইএল দেখায়, পরবর্তীকালে সমাবেশগুলি আইএল-তে বিচ্ছিন্ন করে এবং সেই আইএল থেকে সমতুল্য সি # পুনরায় উত্পন্ন করতে পারে। এখানে আরো একটা বিল্ট-ইন (ILDASM নামক টুল msdn.microsoft.com/en-us/library/f7dy01k1(v=vs.80).aspx ) বোঝার আইএল একটি চতুর thing- দেখতে codebetter.com/raymondlewallen/2005/
02/07

85

ক্রিস শাইনের উত্তর খুব ভাল। যে ব্যক্তিটি স্ট্রিং কনটেনটেশন অপটিমাইজার লিখেছেন আমি কেবল দুটি অতিরিক্ত আকর্ষণীয় পয়েন্ট যুক্ত করব।

প্রথমটি হ'ল সংক্ষিপ্তকরণ অপ্টিমাইজার মূলত উভয় প্রথম বন্ধনী এবং বাম সাহচর্যকে উপেক্ষা করে যখন এটি নিরাপদে এটি করতে পারে। ধরুন আপনার কাছে একটি পদ্ধতি এম () রয়েছে যা একটি স্ট্রিং প্রদান করে। যদি তুমি বল:

string s = M() + "A" + "B";

তারপরে সংকলকটি যুক্ত করে যে সংযোজন অপারেটরটি সহচর থাকে এবং তাই এটি এর মতোই:

string s = ((M() + "A") + "B");

কিন্তু এই:

string s = "C" + "D" + M();

হিসাবে একই

string s = (("C" + "D") + M());

সুতরাং এটি সঙ্গে ধ্রুবক স্ট্রিং এর সংক্ষিপ্তকরণ"CD"M()

বস্তুত, সংযুক্তকরণের অপটিমাইজার বুঝতে পারবেন যে স্ট্রিং সংযুক্তকরণের হয় মিশুক , এবং উত্পন্ন String.Concat(M(), "AB")প্রথম উদাহরণস্বরূপ, যে যদিও বাম associativity লঙ্ঘন করে।

আপনি এমনকি এটি করতে পারেন:

string s = (M() + "E") + ("F" + M()));

এবং আমরা এখনও জেনারেট করব String.Concat(M(), "EF", M())

দ্বিতীয় আকর্ষণীয় বিষয়টি হ'ল নাল এবং খালি স্ট্রিংগুলি অপ্টিমাইজ করা আছে। সুতরাং আপনি যদি এটি করেন:

string s = (M() + "") + (null + M());

তুমি পাবে String.Concat(M(), M())

তারপরে একটি আকর্ষণীয় প্রশ্ন উত্থাপিত হয়: এটি কী?

string s = M() + null;

আমরা এটিকে নিখুঁত করতে পারি না

string s = M();

কারণ শূন্য ফিরে M()আসতে পারে, কিন্তু String.Concat(M(), null)একটি শূন্য স্ট্রিং M()ফিরে আসে যদি নাল ফিরে। সুতরাং আমরা কি পরিবর্তে হ্রাস করা হয়

string s = M() + null;

প্রতি

string s = M() ?? "";

এর মাধ্যমে প্রমাণিত হয় যে স্ট্রিং কনটেনটেশন আসলে একেবারেই কল String.Concatকরার দরকার নেই ।

এই বিষয়ে আরও পড়ার জন্য, দেখুন

স্ট্রিং.কনকাট স্ট্রিংবিল্ডার.অ্যাপেন্ডে কেন অনুকূলিত হয় না?


আমি মনে করি সেখানে বেশ কয়েকটি ত্রুটি পিছলে যেতে পারে। অবশ্যই, ("C" + "D") + M())উত্পন্ন String.Concat("CD", M()), না String.Concat(M(), "AB")। এবং আরও নিচে, (M() + "E") + (null + M())উত্পন্ন করা উচিত String.Concat(M(), "E", M()), না String.Concat(M(), M())
হামার

21
প্রারম্ভিক অনুচ্ছেদের জন্য +1। :) স্ট্যাক ওভারফ্লো সম্পর্কে এই জাতীয় উত্তরগুলি সর্বদা আমাকে অবাক করে।
brichins

23

আমি উত্তরটি এমএসডিএন-তে পেয়েছি। এক.

কীভাবে: একাধিক স্ট্রিং কনটেনেট (সি # প্রোগ্রামিং গাইড)

সংযুক্তি একটি স্ট্রিংকে অন্য স্ট্রিংয়ের শেষে যুক্ত করার প্রক্রিয়া। আপনি যখন + অপারেটর ব্যবহার করে স্ট্রিং লিটারালস বা স্ট্রিং ধ্রুবককে একত্রীকরণ করেন, সংকলকটি একটি একক স্ট্রিং তৈরি করে। কোনও রান টাইম কনটেনটেশন হয় না। যাইহোক, স্ট্রিং ভেরিয়েবলগুলি কেবল রান সময়েই সংযুক্ত করা যায়। এই ক্ষেত্রে, আপনার বিভিন্ন পদ্ধতির কর্মক্ষমতা সম্পর্কে বোঝা উচিত।


22

শুধু একটি. সি # সংকলক স্ট্রিং ধ্রুবকগুলিকে ভাঁজ করবে এবং তাই এটি মূলত নিচে সংকলন করে

String result = "1234";

আমি ভেবেছিলাম আপনি যখনই "" ব্যবহার করবেন তখন এটি একটি স্ট্রিং অবজেক্ট তৈরি করে।
হালকা

1
@ উইলিয়াম সাধারণভাবে হ্যাঁ। তবে অবিচ্ছিন্ন ভাঁজ অপ্রয়োজনীয় মধ্যবর্তী পদক্ষেপগুলি সরিয়ে ফেলবে
জেয়ার্ডপাড়

13

আমি সন্দেহ করি এটি কোনও মানক বা অনুমান দ্বারা বাধ্যতামূলক। একটি সংস্করণ সম্ভবত অন্যের থেকে আলাদা কিছু করতে পারে।


3
এটি কমপক্ষে মাইক্রোসফ্টের সি # কমপ্লেয়ারের জন্য ভিএস ২০০৮ এবং ২০১০ এর জন্য ডকুমেন্টেড আচরণ হিসাবে রয়েছে (@ ডেভিড-স্ট্রাটনের উত্তর দেখুন)। এটি বলেছিল, আপনি ঠিক বলেছেন - যত তাড়াতাড়ি আমি द्रुत অনুভূতি থেকে বলতে পারি, সি # স্পেস এটি নির্দিষ্ট করে না এবং সম্ভবত এটি বাস্তবায়নের বিশদ হিসাবে বিবেচনা করা উচিত।
ক্রিস শাইন

13

এক, যেহেতু তারা অচল, তাই সংকলক সংকলন সময়ে একটি একক স্ট্রিং এ এটি অনুকূলিত করতে সক্ষম হবে।

যদি তারা গতিশীল হয়ে থাকে তবে তারা স্ট্রিং.কনক্যাটকে (স্ট্রিং, স্ট্রিং, স্ট্রিং, স্ট্রিং) একক কলটিতে অনুকূলিত হয়েছিল ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.