লুপের পরে একটি স্ট্রিং বাফার / বিল্ডার সাফ করা হচ্ছে


122

জাভাতে স্ট্রিং বাফারটি আপনি কীভাবে একটি লুপের পরে সাফ করবেন যাতে পরবর্তী পুনরাবৃত্তিটি একটি পরিষ্কার স্ট্রিং বাফার ব্যবহার করে?


2
আরেকটি প্রশ্ন: আপনি কেবল লুপের একটি পুনরাবৃত্তির জন্য কেন একটি এসবি ব্যবহার করেন? অন্য অভ্যন্তর পুনরাবৃত্তি আছে? আপনি যদি কেবল A + B + C + D করতে চান তবে এসবি উপযুক্ত নয় (জাভা সংকলক অভ্যন্তরীণভাবে একটি এসবি ব্যবহার করবে)। আপনি শর্তাধীন স্ট্রিংগুলির কিছু অংশ যুক্ত করতে চাইলে এটি সহায়তা করে তবে অন্যথায় ... কেবল "+" ব্যবহার করুন।
হিলিওস

উত্তর:


135

একটি বিকল্প হ'ল মুছে ফেলা পদ্ধতিটি নিম্নরূপ ব্যবহার করুন:

StringBuffer sb = new StringBuffer();
for (int n = 0; n < 10; n++) {
   sb.append("a");

   // This will clear the buffer
   sb.delete(0, sb.length());
}

আরেকটি বিকল্প (বিট ক্লিনার) সেটলেন্থ (ইন লেন) ব্যবহার করে :

sb.setLength(0);

আরও তথ্যের জন্য জাভাদোক দেখুন :


15
কিছুটা কম আবর্জনা হ'ল কেবল লুপের অভ্যন্তরে স্ট্রিংবাফারটি ঘোষণা করা।
মার্ক ইলিয়ট

11
আহ, আমি sb.setLength (0) মনে করি; এটি লুপের ভিতরে ঘোষণার চেয়ে পরিষ্কার এবং আরও দক্ষ। আপনার সমাধান স্ট্রিংবুফার ব্যবহারের পারফরম্যান্স সুবিধার বিরুদ্ধে যায় ...
জন

6
আমি মনে করি পারফরম্যান্স সুবিধাটি স্ট্রিং মিউটিবিলিটি থেকে আসে, ইনস্ট্যান্টেশনটি সংরক্ষণ করে নয়। এখানে 1e8 পুনরাবৃত্তির একটি দ্রুত পরীক্ষা করা হচ্ছে: ভিতরে লুপ (2.97s): আইডোন.com / .com / yyTL14w , লুপের বাইরে (২.s87 দশক): আদর্শ one.com/F9lgsIxh
মার্ক এলিয়ট

6
পারফরম্যান্সের কথা বলছি: যদি না আপনার কোডটি একাধিক-থ্রেড দৃশ্যে অ্যাক্সেস করা হয়, আপনার স্ট্রিংবফারের চেয়ে স্ট্রিংবিল্ডার ব্যবহার করা উচিত - জাভাদোক দেখুন: "যেখানে সম্ভব, এটি সুপারিশ করা হয় যে এই ক্লাসটি স্ট্রিংবাফারের পছন্দ হিসাবে ব্যবহার করা হবে কারণ এটি অধীনে তত দ্রুত হবে under সর্বাধিক বাস্তবায়ন "।
রাহেল লাথি

4
বাইরে এসবি তৈরির একমাত্র সুবিধা হ'ল এর অভ্যন্তরীণ (সম্ভাব্য দীর্ঘ) চরটি হারাচ্ছেন না। যদি প্রথম পুনরুক্তি ব্যবস্থায় এটি যথেষ্ট পরিমাণে বেড়ে যায় তবে দ্বিতীয় লুপের জন্য কোনও চর [[] আকার পরিবর্তন করতে হবে না। তবে সুবিধা পাওয়ার জন্য "পরিষ্কার পদ্ধতি" অভ্যন্তরীণ অ্যারের আকার সংরক্ষণ করতে হবে। সেটলেন্থ এটি করে তবে এটি এসবিতে ব্যবহৃত না হওয়া সমস্ত অক্ষরকে সেট করে so u0000, সুতরাং এটি কম পারফরম্যান্স যে কেবল একটি ভাল প্রাথমিক ক্ষমতা সহ একটি নতুন এসবি তৈরি করে। লুপের ভিতরে ঘোষণা করা আরও ভাল।
হিলিওস

48

এর পুনরায় StringBufferব্যবহারের সহজ উপায় হ'ল পদ্ধতিটি ব্যবহার করাsetLength()

public void setLength(int newLength)

আপনার মত মামলা হতে পারে

StringBuffer sb = new StringBuffer("HelloWorld");
// after many iterations and manipulations
sb.setLength(0);
// reuse sb

2
@ মমহমুদ, কোড উদাহরণে এটির setLengthপরিবর্তে পড়া উচিত setlength
ওনাবাই

যখন আমি সেটলেন্থ কোড উত্সটি দেখি, এটি কীভাবে কাজ করছে ( gist.github.com/ebuildy/e91ac6af2ff8a6b1821d18abf2f8c9e1 ) এখানে গণনাটি সর্বদা নতুন দৈর্ঘ্য (0) এর চেয়ে বেশি হবে?
টমাস ডেকাক্স

20

আপনার দুটি বিকল্প রয়েছে:

হয় ব্যবহার:

sb.setLength(0);  // It will just discard the previous data, which will be garbage collected later.  

বা ব্যবহার করুন:

sb.delete(0, sb.length());  // A bit slower as it is used to delete sub sequence.  

বিঃদ্রঃ

লুপের মধ্যে ডিক্লেয়ারিং StringBufferবা StringBuilderঅবজেক্টগুলি এড়িয়ে চলুন অন্যথায় এটি প্রতিটি পুনরাবৃত্তির সাহায্যে নতুন অবজেক্ট তৈরি করবে। অবজেক্ট তৈরিতে সিস্টেমের সংস্থান, স্থান প্রয়োজন এবং সময়ও লাগে। সুতরাং দীর্ঘ সময়ের জন্য, যদি সম্ভব হয় তবে এগুলি লুপের মধ্যে ঘোষণা করা থেকে বিরত করুন।



5

আমি প্রতিটি পুনরাবৃত্তির জন্য একটি নতুন StringBuffer(বা আরও ভাল StringBuilder) তৈরি করার পরামর্শ দিচ্ছি । পারফরম্যান্সের পার্থক্যটি সত্যিই নগন্য, তবে আপনার কোডটি খাটো এবং সহজ হবে।


2
আপনার যদি এইরকম পারফরম্যান্স পার্থক্যের কোনও প্রমাণ থাকে তবে দয়া করে এটি ভাগ করুন। (জাভা বেশিরভাগ কোথায় ব্যবহৃত হয়, এবং "বেশিরভাগ" এর সংজ্ঞা অনুসারে আমি পরিসংখ্যানগুলি দেখেও আনন্দিত হব।)
এলি আচেরকান

1
এটি সুপরিচিত যে বরাদ্দকরণ (জাভাতে নতুন কীওয়ার্ড) একই জিনিসটির কিছু ক্ষেত্র পরিবর্তনের চেয়ে ব্যয়বহুল। "বেশিরভাগ ক্ষেত্রে", যার জন্য আপনি অত্যন্ত উচ্চারণ করতে পারেন, জাভা ব্যবহার করে সব থেকে 1.5 বিলিয়ন অ্যান্ড্রয়েড ডিভাইস রয়েছে।
লুই সিএডি

1
আমি সম্মত হই যে কিছু ক্ষেত্রে, কোড পঠনযোগ্যতা পারফরম্যান্সের চেয়ে বেশি গুরুত্বপূর্ণ তবে এই ক্ষেত্রে এটি কোডের একমাত্র লাইন! এবং আপনি একটি বেঞ্চমার্ক চালাতে পারেন যা আপনাকে প্রমাণ করবে যে বরাদ্দ এবং অবজেক্ট তৈরি, প্লাস জঞ্জাল সংগ্রহ আদৌ না করার চেয়ে ব্যয়বহুল। যেহেতু আমরা একটি লুপে আছি, এটি প্রাসঙ্গিকের চেয়ে বেশি।
লুই সিএডি

1
আমি নুথের দৃষ্টিভঙ্গিতেও সাবস্ক্রাইব করেছিলাম, তবে তার দৃষ্টিভঙ্গি সবসময় সত্য হয় না। যোগ করার পদ্ধতি মাত্র এক লাইন সম্ভাব্য লাভ CPU- র চক্র এবং মেমরি একেবারে মন্দ নয়। আপনি ধারণাটি খুব সোজা করে নিচ্ছেন। নোট করুন যে একটি লুপ সাধারণত বহুবার পুনরাবৃত্তি হয়। একটি লুপ হাজার হাজার বার পুনরাবৃত্তি করা যেতে পারে, যা সাবধানতার সাথে অপ্টিমাইজড না হলে মোবাইলে (এবং সার্ভার বা কম্পিউটারেও) মূল্যবান মেগাবাইট খেতে পারে।
লুই সিএডি

1
আমি মনে করি আমরা উভয়ই আমাদের দৃষ্টিভঙ্গি পরিষ্কারভাবে যথেষ্ট বর্ণনা করেছি, এবং আমি অনুভব করি যে এই মন্তব্য বিভাগে আরও আলোচনা উপকারী হবে না। আপনি যদি মনে করেন যে আমার উত্তরটি ভুল, বিভ্রান্তিমূলক বা অসম্পূর্ণ, তবে আপনি - বা যে কেউ - যেকোন উপায়েই এটি সম্পাদনা এবং / অথবা ডাউনওয়েটে স্বাগত।
এলি আচেরকান

5
public void clear(StringBuilder s) {
    s.setLength(0);
}

ব্যবহার:

StringBuilder v = new StringBuilder();
clear(v);

পাঠযোগ্যতার জন্য, আমি মনে করি এটিই সেরা সমাধান।


2

ইতিমধ্যে সেখানে ভাল উত্তর। স্ট্রিংবুফার এবং স্ট্রিংবিল্ড পারফরম্যান্স পার্থক্যের জন্য কেবল একটি মানদণ্ডের ফলাফল যুক্ত করুন লুপে নতুন উদাহরণ ব্যবহার করুন বা লুপে সেটলেন্থ (0) ব্যবহার করুন।

সংক্ষিপ্তসারটি হ'ল: একটি বড় লুপে

  • স্ট্রিংবুডার স্ট্রিংবুফারের চেয়ে অনেক দ্রুত
  • লুপে নতুন স্ট্রিংবিল্ডার উদাহরণ তৈরি করুন সেটলেন্থ (0) এর সাথে কোনও পার্থক্য নেই। (setLength (0) এর নতুন উদাহরণ তৈরি করার চেয়ে খুব খুব ক্ষুদ্র সুবিধা রয়েছে))
  • স্ট্রিংবুফার লুপে নতুন উদাহরণ তৈরি করে স্ট্রিংবিল্ডারের চেয়ে ধীর
  • স্ট্রিংবুফারের সেটলেন্থ (0) লুপে নতুন ইনস্ট্যান্স তৈরির চেয়ে অত্যন্ত ধীর।

খুব সাধারণ মানদণ্ড (আমি কেবল কোডটি ম্যানুয়ালি পরিবর্তিত করেছি এবং বিভিন্ন পরীক্ষা করি):

public class StringBuilderSpeed {
public static final char ch[] = new char[]{'a','b','c','d','e','f','g','h','i'};

public static void main(String a[]){
    int loopTime = 99999999;
    long startTime = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder();
    for(int i = 0 ; i < loopTime; i++){
        for(char c : ch){
            sb.append(c);
        }
        sb.setLength(0);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time cost: " + (endTime - startTime));
}

}

লুপে নতুন স্ট্রিংবিল্ডার উদাহরণ: সময় ব্যয়: 3693, 3862, 3624, 3742

স্ট্রিংবিল্ডার সেট দৈর্ঘ্য: সময় ব্যয়: 3465, 3421, 3557, 3408

লুপে নতুন স্ট্রিংবফার উদাহরণ: সময় ব্যয়: 8327, 8324, 8284

স্ট্রিংবাফার সেট দৈর্ঘ্যের সময় ব্যয়: 22878, 23017, 22894

স্ট্রিংবুডার সেটলেন্থ :-) জন্য আমার ল্যাপটপটি এত দীর্ঘ ব্যবহার করার জন্য কিছু সমস্যা পেয়েছে না তা নিশ্চিত করার জন্য আবার স্ট্রিংবিল্ডার সেটলেন্থ সেট করে Time


0
StringBuffer sb = new SringBuffer();
// do something wiht it
sb = new StringBuffer();

আমি মনে করি এই কোডটি আরও দ্রুত।


3
এটিতে পারফরম্যান্স সংক্রান্ত সমস্যা থাকবে। এটি প্রতিটি পুনরাবৃত্তির পরে একটি নতুন অবজেক্ট তৈরি করে
আদিত্য সিং

@ আদিত্যসিংহ এটি পুরোপুরি যুক্তিসঙ্গত পন্থা। প্রমাণ ছাড়াই পারফরম্যান্সের সমস্যাগুলি ধরে করবেন না।
shmosel

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