জাভা এর স্ট্রিংয়ের সময় জটিলতা ()


উত্তর:


137

নতুন উত্তর

জাভা's এর জীবদ্দশায় আপডেট update হিসাবে, substringএকটি অনুলিপি তৈরির পরিবর্তিত আচরণ - তাই প্রত্যেকটি Stringএমন কোনও বিষয়কে বোঝায় char[]যা যতক্ষণ না আমি অবগত আছি অন্য কোনও অবজেক্টের সাথে ভাগ করা হয়নি । সুতরাং এই মুহুর্তে, substring()একটি ও (এন) অপারেশন হয়ে ওঠে যেখানে n হ'ল স্ট্রিংগুলিতে সংখ্যা।

পুরানো উত্তর: প্রাক জাভা 7

Undocumented - তবে অনুশীলনে O (1) আপনি যদি ধরে নেন যে কোনও আবর্জনা সংগ্রহের প্রয়োজন নেই, ইত্যাদি।

এটি কেবল Stringএকই অন্তর্নিহিত char[]তবে বিভিন্ন অফসেট এবং গণনা মান সহ একটি নতুন অবজেক্ট তৈরি করে । সুতরাং ব্যয়টি বৈধতা সম্পাদন করতে এবং একক নতুন (যুক্তিসঙ্গতভাবে ছোট) অবজেক্ট তৈরি করতে সময় নেয়। এটি ও (1) যতক্ষণ না আবর্জনা সংগ্রহ, সিপিইউ ক্যাশে ইত্যাদির উপর ভিত্তি করে সময়ের সাথে পরিবর্তিত হতে পারে এমন ক্রিয়াকলাপগুলির জটিলতার বিষয়ে কথা বলা বুদ্ধিমানের, বিশেষত, এটি সরাসরি মূল স্ট্রিংয়ের দৈর্ঘ্য বা স্ট্রিংয়ের উপর নির্ভর করে না ।


14
"Undocumented" এর জন্য +1, এটি API এর দুর্ভাগ্যজনক দুর্বলতা।
রাইডওয়াল্ড

10
এটা দুর্বলতা নয়। যদি আচরণ নথিভুক্ত করা হয় এবং বাস্তবায়নের বিশদটি না থাকে তবে এটি ভবিষ্যতে দ্রুত বাস্তবায়নের অনুমতি দেয়। সাধারণভাবে, জাভা প্রায়শই আচরণের সংজ্ঞা দেয় এবং প্রয়োগগুলি সর্বোত্তম উপায় কী তা সিদ্ধান্ত নিতে দেয়। অন্য কথায় - আপনার যত্ন নেওয়া উচিত নয়, সর্বোপরি, এটি জাভা ;-)
পীনেট

4
শুভ পয়েন্ট চিনাবাদাম, এমনকি যদি আমি দৃly়ভাবে বিশ্বাস করি তবে তারা এটিকে ও (1) এর চেয়ে দ্রুত তৈরি করতে সক্ষম হবে।
আবাহগাত

9
না, এর মতো কিছু নথিভুক্ত করা উচিত। কোনও বিকাশকারীকে সচেতন হওয়া উচিত, যদি সে বড় স্ট্রিংয়ের একটি ছোট ছোট স্ট্রিং নেওয়ার পরিকল্পনা করে তবে বৃহত্তর স্ট্রিংটি নেট। নেট-এর মতোই জঞ্জাল সংগ্রহ হবে বলে আশা করে।
কিওয়ারটি

4
@ আইভায়লোটোসকভ: অনুলিপি করা অক্ষরের সংখ্যা।
জন স্কিটি

33

এটি জাভার পুরানো সংস্করণগুলিতে ও (1) ছিল - যেমন জন বলেছেন, এটি ঠিক একই অন্তর্নিহিত চর [], এবং একটি আলাদা অফসেট এবং দৈর্ঘ্য সহ একটি নতুন স্ট্রিং তৈরি করেছে।

তবে এটি আসলে জাভা 7 আপডেট 6 দিয়ে শুরু হয়েছে।

চর [] ভাগ করে নেওয়া মুছে ফেলা হয়েছে, এবং অফসেট এবং দৈর্ঘ্যের ক্ষেত্রগুলি সরানো হয়েছে। সাবস্ট্রিং () এখন কেবলমাত্র সমস্ত অক্ষরকে একটি নতুন স্ট্রিংয়ে অনুলিপি করে।

তবে, জাভা 7 আপডেট 6 এ সাবস্ট্রিং হ'ল ও (এন)


4
+1 সাম্প্রতিক সান জাভা এবং ওপেনজেডিকে সংস্করণগুলিতে এটি সত্যই। জিএনইউ ক্লাসপাথ (এবং অন্যান্যরা, আমি ধরে নিই) এখনও পুরানো দৃষ্টান্ত ব্যবহার করছেন। দুর্ভাগ্যক্রমে কিছুটা বৌদ্ধিক জড়তা এটাকে মনে হচ্ছে। আমি এখনও 2013 সালে পোস্টগুলি দেখি যে সাবস্ট্রিংগুলি একটি ভাগ করে নেওয়া অনুমানের ভিত্তিতে বিভিন্ন পদ্ধতির সুপারিশ করছে char[]...
থকালা

10
সুতরাং নতুন সংস্করণে আর ও (1) জটিলতা নেই। জানতে আগ্রহী ও (1) এ সাবস্ট্রিং বাস্তবায়নের কোনও বিকল্প উপায় আছে কি? স্ট্রিং.স্যাবস্ট্রিং একটি অত্যন্ত কার্যকর পদ্ধতি।
ইয়েতং চিউ

8

এটি এখন লিনিয়ার জটিলতা। এটি স্ট্রিংয়ের জন্য মেমরি ফুটো ইস্যুটি ঠিক করার পরে।

সুতরাং জাভা ১.7.০.০66 থেকে মনে রাখবেন যে স্ট্রিং.সুবস্ট্রিংয়ের এখন ধ্রুবকটির পরিবর্তে রৈখিক জটিলতা রয়েছে।


সুতরাং এটি এখন খারাপ (দীর্ঘ স্ট্রিং জন্য)?
পিটার মর্টেনসেন

@ পিটারমোরটেনসেন হ্যাঁ
ইডো কেসলার

3

জনের উত্তরে প্রমাণ যুক্ত করা। আমার একই সন্দেহ ছিল এবং স্ট্রিংয়ের দৈর্ঘ্যের স্ট্রিং ফাংশনে কোনও প্রভাব আছে কিনা তা পরীক্ষা করে দেখতে চেয়েছিলাম। কোন প্যারামিটার সাবস্ট্রিং আসলে নির্ভর করে তা পরীক্ষা করতে নিম্নলিখিত কোডটি লিখিত।

import org.apache.commons.lang.RandomStringUtils;

public class Dummy {

    private static final String pool[] = new String[3];
    private static int substringLength;

    public static void main(String args[]) {
        pool[0] = RandomStringUtils.random(2000);
        pool[1] = RandomStringUtils.random(10000);
        pool[2] = RandomStringUtils.random(100000);
        test(10);
        test(100);
        test(1000);
    }

    public static void test(int val) {
        substringLength = val;
        StatsCopy statsCopy[] = new StatsCopy[3];
        for (int j = 0; j < 3; j++) {
            statsCopy[j] = new StatsCopy();
        }
        long latency[] = new long[3];
        for (int i = 0; i < 10000; i++) {
            for (int j = 0; j < 3; j++) {
                latency[j] = latency(pool[j]);
                statsCopy[j].send(latency[j]);
            }
        }
        for (int i = 0; i < 3; i++) {
            System.out.println(
                    " Avg: "
                            + (int) statsCopy[i].getAvg()
                            + "\t String length: "
                            + pool[i].length()
                            + "\tSubstring Length: "
                            + substringLength);
        }
        System.out.println();
    }

    private static long latency(String a) {
        long startTime = System.nanoTime();
        a.substring(0, substringLength);
        long endtime = System.nanoTime();
        return endtime - startTime;
    }

    private static class StatsCopy {
        private  long count = 0;
        private  long min = Integer.MAX_VALUE;
        private  long max = 0;
        private  double avg = 0;

        public  void send(long latency) {
            computeStats(latency);
            count++;
        }

        private  void computeStats(long latency) {
            if (min > latency) min = latency;
            if (max < latency) max = latency;
            avg = ((float) count / (count + 1)) * avg + (float) latency / (count + 1);
        }

        public  double getAvg() {
            return avg;
        }

        public  long getMin() {
            return min;
        }

        public  long getMax() {
            return max;
        }

        public  long getCount() {
            return count;
        }
    }

}

জাভা 8 এ কার্যকর করার ফলাফল রয়েছে:

 Avg: 128    String length: 2000    Substring Length: 10
 Avg: 127    String length: 10000   Substring Length: 10
 Avg: 124    String length: 100000  Substring Length: 10

 Avg: 172    String length: 2000    Substring Length: 100
 Avg: 175    String length: 10000   Substring Length: 100
 Avg: 177    String length: 100000  Substring Length: 100

 Avg: 1199   String length: 2000    Substring Length: 1000
 Avg: 1186   String length: 10000   Substring Length: 1000
 Avg: 1339   String length: 100000  Substring Length: 1000

স্ট্রিংয়ের দৈর্ঘ্যের উপর ভিত্তি করে অনুরোধ করা স্ট্রিংয়ের দৈর্ঘ্যের উপর নির্ভর করে স্ট্রিংয়ের কার্যকারিতা নির্ভর করে।


1

ও (1) কারণ মূল স্ট্রিংয়ের কোনও অনুলিপি করা হয়নি, এটি কেবলমাত্র বিভিন্ন অফসেট তথ্য সহ একটি নতুন র‍্যাপার অবজেক্ট তৈরি করে।


1

অনুসরণ থেকে নিজেকে বিচার করুন, তবে জাভার পারফরম্যান্সের ঘাটতিগুলি অন্য কোথাও রয়েছে, এখানে স্ট্রিংয়ের বিকল্পগুলি নেই। কোড:

public static void main(String[] args) throws IOException {

        String longStr = "asjf97zcv.1jm2497z20`1829182oqiwure92874nvcxz,nvz.,xo" + 
                "aihf[oiefjkas';./.,z][p\\°°°°°°°°?!(*#&(@*&#!)^(*&(*&)(*&" +
                "fasdznmcxzvvcxz,vc,mvczvcz,mvcz,mcvcxvc,mvcxcvcxvcxvcxvcx";
        int[] indices = new int[32 * 1024];
        int[] lengths = new int[indices.length];
        Random r = new Random();
        final int minLength = 6;
        for (int i = 0; i < indices.length; ++i)
        {
            indices[i] = r.nextInt(longStr.length() - minLength);
            lengths[i] = minLength + r.nextInt(longStr.length() - indices[i] - minLength);
        }

        long start = System.nanoTime();

        int avoidOptimization = 0;
        for (int i = 0; i < indices.length; ++i)
            //avoidOptimization += lengths[i]; //tested - this was cheap
            avoidOptimization += longStr.substring(indices[i],
                    indices[i] + lengths[i]).length();

        long end = System.nanoTime();
        System.out.println("substring " + indices.length + " times");
        System.out.println("Sum of lengths of splits = " + avoidOptimization);
        System.out.println("Elapsed " + (end - start) / 1.0e6 + " ms");
    }

আউটপুট:

32768 বার বিস্তৃত
বিভাজনের দৈর্ঘ্যের যোগফল = 1494414
বিদায় নিয়েছে 2.446679 এমএস

এটি ও (1) হয় বা না হলে নির্ভর করে। আপনি যদি মেমরির ক্ষেত্রে কেবল একই স্ট্রিংটিকে উল্লেখ করেন তবে খুব দীর্ঘ স্ট্রিংটি কল্পনা করুন , আপনি সাবস্ট্রিং তৈরি করেন এবং দীর্ঘকে উল্লেখ করা বন্ধ করেন stop দীর্ঘ একের জন্য মেমরি প্রকাশ করতে ভাল লাগবে না?


0

জাভা 1.7.0_06 এর আগে : ও (1)

জাভা 1.7.0_06 এর পরে : ও (এন)। স্মৃতি ফাঁস হওয়ার কারণে এটি পরিবর্তন করা হয়েছিল। ক্ষেত্রগুলি offsetএবং countস্ট্রিং থেকে অপসারণের পরে , সাবস্ট্রিং বাস্তবায়ন ও (এন) হয়ে যায়।

আরও তথ্যের জন্য, দয়া করে দেখুন: http://java-performance.info/changes-to-string-java-1-7-0_06/

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