পারফরম্যান্স বেঞ্চমার্ক সহ প্রধান উত্তরগুলির মূল্যায়ন যা উদ্বেগকে নিশ্চিত করে যে বর্তমান নির্বাচিত উত্তরটি হুডের অধীনে ব্যয়বহুল রেজেক্স অপারেশন করে
আজ পর্যন্ত সরবরাহিত উত্তরগুলি 3 টি মূল শৈলীতে আসে (জাভাস্ক্রিপ্ট উত্তর উপেক্ষা করে;)):
- স্ট্রিং.রেপ্লেস ব্যবহার করুন ("টুডিলিট," "); যা হুডের নিচে রেজেক্স ব্যবহার করে
- লাম্বদা ব্যবহার করুন
- সাধারণ জাভা বাস্তবায়ন ব্যবহার করুন
কোড আকারের ক্ষেত্রে স্পষ্টভাবে স্ট্রিং.রেপ্লেস সবচেয়ে ক্ষতিকারক। সহজ জাভা প্রয়োগটি ল্যাম্বদার তুলনায় কিছুটা ছোট এবং ক্লিনার (আইএমএইচও) (আমাকে ভুল করবেন না - আমি ল্যাম্বডাস প্রায়শই যেখানে তারা উপযুক্ত সেগুলি ব্যবহার করি)
এক্সিকিউশন স্পিডটি ছিল দ্রুততম থেকে ধীর করার জন্য: সাধারণ জাভা বাস্তবায়ন, লাম্বদা এবং তারপরে স্ট্রিং.রেপ্লেস () (যেটি রিজেক্সকে আহ্বান করে)।
এতদূর দ্রুততম বাস্তবায়নটি ছিল জাভা বাস্তবায়নটির সাথে সুরযুক্ত যাতে এটি স্ট্রিংবিল্ডার বাফারটিকে সর্বাধিক সম্ভাব্য ফলাফলের দৈর্ঘ্যে প্রিলোকলেট করে এবং তারপরে কেবল "অক্ষর মুছতে অক্ষর" স্ট্রিংগুলিতে নেই এমন বাফারে অক্ষর যুক্ত করে। এটি স্ট্রিংস> 16 টি অক্ষরের দৈর্ঘ্যের (স্ট্রিংবিল্ডারের জন্য ডিফল্ট বরাদ্দ) এর জন্য ঘটে যাওয়া কোনও পুনঃনির্দেশগুলি এড়িয়ে যায় এবং এটি স্ট্রিংয়ের অনুলিপি থেকে অক্ষরগুলি মুছে ফেলার "স্লাইড বাম" পারফরম্যান্সটিকে এড়িয়ে যায় লাম্বদা বাস্তবায়ন।
নীচের কোডটি একটি সাধারণ বেঞ্চমার্ক পরীক্ষা চালায়, প্রতিটি বাস্তবায়নকে 1,000,000 বার চালায় এবং অতিবাহিত সময় লগ করে।
প্রতিটি ফলাফলের সাথে সঠিক ফলাফলগুলি পরিবর্তিত হয় তবে কার্য সম্পাদনের ক্রমটি কখনই পরিবর্তিত হয় না:
Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms
ল্যাম্বডা বাস্তবায়ন (ক্যাপলানের উত্তর থেকে অনুলিপি করা) ধীর হতে পারে কারণ এটি অক্ষরটি মুছে ফেলা হতে ডানদিকে সমস্ত অক্ষরের একটি "এক বাম শিফট" সম্পাদন করে। এটি মুছে ফেলার জন্য প্রয়োজনীয় প্রচুর অক্ষরের সাথে দীর্ঘতর স্ট্রিংগুলির জন্য সম্ভবত আরও খারাপ হবে। এছাড়াও ল্যাম্বদা বাস্তবায়নে নিজেই কিছু ওভারহেড থাকতে পারেন।
স্ট্রিং.রেপ্লেস বাস্তবায়ন, রেজেক্স ব্যবহার করে এবং প্রতিটি কলে একটি রেজেক্স "সংকলন" করে। এর একটি অপ্টিমাইজেশন হ'ল প্রত্যক্ষভাবে রেগেক্স ব্যবহার করা এবং প্রতিটি বার সংকলনের ব্যয় এড়াতে সংকলিত প্যাটার্নটি ক্যাশে করা।
package com.sample;
import java.util.function.BiFunction;
import java.util.stream.IntStream;
public class Main {
static public String deleteCharsSimple(String fromString, String charsToDelete)
{
StringBuilder buf = new StringBuilder(fromString.length()); // Preallocate to max possible result length
for(int i = 0; i < fromString.length(); i++)
if (charsToDelete.indexOf(fromString.charAt(i)) < 0)
buf.append(fromString.charAt(i)); // char not in chars to delete so add it
return buf.toString();
}
static public String deleteCharsLambda(String fromString1, String charsToDelete)
{
BiFunction<String, String, String> deleteChars = (fromString, chars) -> {
StringBuilder buf = new StringBuilder(fromString);
IntStream.range(0, buf.length()).forEach(i -> {
while (i < buf.length() && chars.indexOf(buf.charAt(i)) >= 0)
buf.deleteCharAt(i);
});
return (buf.toString());
};
return deleteChars.apply(fromString1, charsToDelete);
}
static public String deleteCharsReplace(String fromString, String charsToDelete)
{
return fromString.replace(charsToDelete, "");
}
public static void main(String[] args)
{
String str = "XXXTextX XXto modifyX";
String charsToDelete = "X"; // Should only be one char as per OP's requirement
long start, end;
System.out.println("Start simple");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsSimple(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
System.out.println("Start lambda");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsLambda(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
System.out.println("Start replace");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsReplace(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
}
}