জাভাতে চূড়ান্ত কীওয়ার্ড ব্যবহার করা কি কার্যকারিতা উন্নত করে?


347

জাভাতে আমরা অনেকগুলি জায়গা দেখতে পাই যেখানে finalকীওয়ার্ডটি ব্যবহার করা যেতে পারে তবে এর ব্যবহারটি অস্বাভাবিক।

উদাহরণ স্বরূপ:

String str = "abc";
System.out.println(str);

উপরের ক্ষেত্রে, strহতে পারে finalতবে এটি সাধারণত ছেড়ে দেওয়া হয়।

যখন কোনও পদ্ধতি কখনই ওভাররাইড হয় না তখন আমরা চূড়ান্ত কীওয়ার্ডটি ব্যবহার করতে পারি। একইভাবে কোনও বর্গের ক্ষেত্রে যা উত্তরাধিকারসূত্রে প্রাপ্ত হবে না।

এই যে কোনও একটিতে বা সমস্ত ক্ষেত্রে চূড়ান্ত কীওয়ার্ডের ব্যবহার কার্যকারিতা উন্নত করে? যদি তাই হয়, তবে কিভাবে? দয়া করে ব্যাখ্যা করুন. যদি finalপারফরম্যান্সের জন্য সত্যিকারের যথাযথ ব্যবহার গুরুত্বপূর্ণ হয় তবে কীওয়ার্ডটির সর্বোত্তম ব্যবহার করার জন্য কোনও জাভা প্রোগ্রামারকে কী অভ্যাসগুলি বিকাশ করা উচিত?


আমি মনে করি না এতটা পাল, পদ্ধতি প্রেরণ (কল সাইট ক্যাচিং এবং ...) স্থির ধরণের ভাষায় নয় গতিশীল ভাষায় একটি সমস্যা
জাহান

যদি আমি পর্যালোচনা করার উদ্দেশ্যে ব্যবহৃত আমার পিএমডি সরঞ্জামটি (গ্রহনের প্লাগইন) চালনা করি তবে এটি উপরে বর্ণিত হিসাবে পরিবর্তনীয় ক্ষেত্রে পরিবর্তন করার পরামর্শ দেয়। তবে আমি এর ধারণাটি বুঝতে পারি নি। সত্যিই পারফরম্যান্স এত হিট ??
অভিষেক জৈন

5
আমি ভেবেছিলাম এটি একটি সাধারণ পরীক্ষার প্রশ্ন। আমার মনে আছে চূড়ান্ত যে করে কর্মক্ষমতার উপর প্রভাব আছে, IIRC চূড়ান্ত শ্রেণীর কিছু উপায় মধ্যে Jre দ্বারা অপ্টিমাইজ করা যাবে না কারণ তারা subclassed করা যাবে না।
কাওু

আমি আসলে এই পরীক্ষা ছিল। সমস্ত জেভিএমগুলিতে আমি স্থানীয় ভেরিয়েবলগুলিতে ফাইনালের ব্যবহার পরীক্ষা করেছিলাম পারফরম্যান্সকে উন্নত করেছিলাম (সামান্য, তবে তবুও ইউটিলিটি পদ্ধতির একটি কারণ হতে পারে)। উত্স কোডটি নীচে আমার উত্তরে রয়েছে।
rustyx

1
"অকালীন অপটিমাইজেশন হ'ল সমস্ত অশুভের মূল"। সংকলকটিকে এর কাজটি করতে দিন। পঠনযোগ্য এবং ভাল মন্তব্য কোড লিখুন। এটি সর্বদা সেরা পছন্দ!
কায়সার

উত্তর:


285

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

(অবশ্যই, এটি ধরে নিচ্ছে আপনি হটস্পট ব্যবহার করছেন - তবে এটি এখন পর্যন্ত সবচেয়ে সাধারণ জেভিএম, তাই ...)

আমার মনে আপনার finalপারফরম্যান্স কারণে নয় বরং সাফ ডিজাইন এবং পঠনযোগ্যতার উপর ভিত্তি করে ব্যবহার করা উচিত । আপনি যদি পারফরম্যান্সের কারণে কোনও পরিবর্তন করতে চান তবে ক্লিয়ারেস্ট কোডটি আকারের বাইরে নমন করার আগে আপনার যথাযথ পরিমাপ করা উচিত - এইভাবে আপনি সিদ্ধান্ত নিতে পারেন যে কোনও অতিরিক্ত সম্পাদনা দরিদ্র পাঠযোগ্যতা / ডিজাইনের পক্ষে মূল্যবান কিনা। (আমার অভিজ্ঞতায় এটি কখনই মূল্যহীন নয়; ওয়াইএমএমভি।)

সম্পাদনা: চূড়ান্ত ক্ষেত্রগুলি যেমন উল্লেখ করা হয়েছে, স্পষ্ট ডিজাইনের ক্ষেত্রে তারা যেহেতু প্রায়শই একটি ভাল ধারণা হ'ল এটি উত্থাপনযোগ্য। তারা ক্রস-থ্রেড দৃশ্যমানতার ক্ষেত্রেও গ্যারান্টিযুক্ত আচরণ পরিবর্তন করে: কোনও কনস্ট্রাক্টর সম্পূর্ণ হওয়ার পরে, কোনও চূড়ান্ত ক্ষেত্রগুলি অন্য থ্রেডগুলিতে তত্ক্ষণাত দৃশ্যমান হওয়ার গ্যারান্টিযুক্ত হয়। এটি finalআমার অভিজ্ঞতার মধ্যে সম্ভবত সবচেয়ে সাধারণ ব্যবহার , যদিও জোশ ব্লচের "উত্তরাধিকারের জন্য নকশা করা বা এটি নিষিদ্ধ করার" থাম্বের নিয়মের সমর্থক হিসাবে আমার সম্ভবত finalক্লাসের জন্য আরও প্রায়ই ব্যবহার করা উচিত ...


1
@ অভিষেক: বিশেষ করে কী সম্পর্কে? সবচেয়ে গুরুত্বপূর্ণ পয়েন্টটি হ'ল শেষটি - এটি সম্পর্কে আপনার অবশ্যই অবশ্যই উদ্বিগ্ন হওয়া উচিত নয়।
জন স্কিটি

9
@ অ্যাবিশেক: finalসাধারণত পরামর্শ দেওয়া হয় কারণ এটি কোড বোঝা সহজ করে তোলে এবং বাগগুলি খুঁজে পেতে সহায়তা করে (কারণ এটি প্রোগ্রামারদের উদ্দেশ্যকে স্পষ্ট করে তোলে)। পিএমডি সম্ভবত finalএই স্টাইল ইস্যুগুলির কারণে ব্যবহারের পরামর্শ দেয় , কার্য সম্পাদনের কারণে নয়।
সলেস্কে

3
@ অভিষেক: এটির বেশিরভাগই সম্ভবত জেভিএম-নির্দিষ্ট হওয়ার সম্ভাবনা রয়েছে এবং এটি প্রসঙ্গে খুব সূক্ষ্ম দিকগুলির উপর নির্ভর করতে পারে। উদাহরণস্বরূপ, আমি বিশ্বাস করি যে হটস্পট সার্ভার জেভিএম এখনও যখন কোনও শ্রেণিতে ওভাররাইড করা যায় তখন ভার্চুয়াল পদ্ধতিগুলির সন্নিবেশকে অনুমতি দেবে, যেখানে উপযুক্ত হবে সেখানে দ্রুত টাইপ চেক সহ। তবে বিশদটি নিখুঁত করা শক্ত এবং এটি প্রকাশের মধ্যে ভাল পরিবর্তন হতে পারে।
জন স্কিটি

5
এখানে আমি, কার্যকর জাভা, 2nd সংস্করণ, আইটেম 15 উদ্ধৃত পরিবর্তনশীলতা ছোট করুন হবে: Immutable classes are easier to design, implement, and use than mutable classes. They are less prone to error and are more secure.। উপরন্তু An immutable object can be in exactly one state, the state in which it was created.বনাম Mutable objects, on the other hand, can have arbitrarily complex state spaces.। আমার ব্যক্তিগত অভিজ্ঞতা থেকে, কীওয়ার্ডটি ব্যবহার করে finalবিকাশকারীর অপরিবর্তনীয়তার দিকে ঝুঁকতে হবে, কোডটি "অনুকূলিতকরণ" নয় highlight আমি এই অধ্যায়টি পড়তে আপনাকে উত্সাহিত করছি, আকর্ষণীয়!
লুই এফ

2
অন্যান্য উত্তরগুলি দেখায় যে finalভেরিয়েবলগুলিতে কীওয়ার্ড ব্যবহার করা বাইটোকোডের পরিমাণ হ্রাস করতে পারে, যা পারফরম্যান্সে প্রভাব ফেলতে পারে।
জুলিয়েন ক্রোনেগ

86

সংক্ষিপ্ত উত্তর: এটি সম্পর্কে চিন্তা করবেন না!

দীর্ঘ উত্তর:

চূড়ান্ত স্থানীয় ভেরিয়েবলগুলি সম্পর্কে কথা বলার সময় মনে রাখবেন যে কীওয়ার্ডটি ব্যবহার করে সংকলকটি স্থিতিশীলভাবেfinal কোডটি অনুকূলিতকরণে সহায়তা করবে , যার পরিণতিতে দ্রুত কোডের ফলাফল হতে পারে। উদাহরণস্বরূপ, a + bনীচের উদাহরণে চূড়ান্ত স্ট্রিংগুলি স্থিরভাবে সংশ্লেষিত হয় (সংকলন সময়ে)।

public class FinalTest {

    public static final int N_ITERATIONS = 1000000;

    public static String testFinal() {
        final String a = "a";
        final String b = "b";
        return a + b;
    }

    public static String testNonFinal() {
        String a = "a";
        String b = "b";
        return a + b;
    }

    public static void main(String[] args) {
        long tStart, tElapsed;

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method with finals took " + tElapsed + " ms");

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testNonFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method without finals took " + tElapsed + " ms");

    }

}

ফলাফল?

Method with finals took 5 ms
Method without finals took 273 ms

জাভা হটস্পট ভিএম 1.7.0_45-বি 18 তে পরীক্ষিত।

তাহলে আসল পারফরম্যান্সের উন্নতি কত? বলতে সাহস পাচ্ছি না। বেশিরভাগ ক্ষেত্রে সম্ভবত প্রান্তিক (এই সিনথেটিক পরীক্ষায় ~ 270 ন্যানো সেকেন্ড কারণ স্ট্রিং কনটেনটেশন পুরোপুরি এড়ানো হয় - একটি বিরল ক্ষেত্রে), তবে অত্যন্ত অনুকূলিত ইউটিলিটি কোডে এটি একটি কারণ হতে পারে। যে কোনও ক্ষেত্রে আসল প্রশ্নের উত্তর হ্যাঁ, এটি পারফরম্যান্সের উন্নতি করতে পারে তবে সর্বোপরি প্রান্তিকভাবে

সংকলন-সময় সুবিধাগুলি একসাথে, আমি কোনও প্রমাণ খুঁজে পাইনি যে কীওয়ার্ডটির ব্যবহারের finalপারফরম্যান্সে কোনও পরিমাপযোগ্য প্রভাব রয়েছে।


2
উভয় ক্ষেত্রেই 100 বার পরীক্ষা করার জন্য আমি আপনার কোডটি একটু লিখে দিয়েছি। অবশেষে ফাইনালের গড় সময় ছিল 0 এমএস এবং নন ফাইনালের জন্য 9 এমএস। 10 মিনিটে পুনরাবৃত্তি গণনা বাড়িয়ে গড়ে 0 এমএস এবং 75 এমএস সেট করে। নন ফাইনালের জন্য সেরা রানটি ছিল 0 এমএস তবে। হতে পারে এটি ভিএম সনাক্তকরণের ফলাফলগুলি কেবল ফেলে দেওয়া হচ্ছে বা কিছু? আমি জানি না, তবে নির্বিশেষে, ফাইনালের ব্যবহার একটি গুরুত্বপূর্ণ পার্থক্য করে।
ক্যাস্পার ফারজমান্ড

5
ত্রুটিযুক্ত পরীক্ষা। পূর্ববর্তী পরীক্ষাগুলি জেভিএমকে উষ্ণ করবে এবং পরবর্তী পরীক্ষার অনুরোধগুলিকে উপকৃত করবে। আপনার পরীক্ষাগুলি পুনরায় অর্ডার করুন এবং দেখুন কী। আপনাকে প্রতিটি পরীক্ষাটি তার নিজস্ব জেভিএম উদাহরণে চালানো দরকার।
স্টিভ কুও

16
কোনও পরীক্ষা ত্রুটিযুক্ত নয়, ওয়ার্মআপটি বিবেচনায় নেওয়া হয়েছিল। দ্বিতীয় পরীক্ষাটি স্লোয়ার, দ্রুত নয়। ওয়ার্মআপ না করে দ্বিতীয় পরীক্ষাটি ইভেন স্লোয়ার হবে।
rustyx

6
টেস্টফিনালে () সর্বক্ষণ স্ট্রিংস পুল থেকে একই বস্তুটি ফেরত দেয়, কারণ চূড়ান্ত স্ট্রিং এবং স্ট্রিংগুলির আস্তরাকের কনস্ট্যান্টেশনগুলির পুনরুক্তি সংকলন সময়ে মূল্যায়ন করা হয়। টেস্টননফাইনাল () প্রতিবার নতুন বস্তু ফিরিয়ে দেয়, গতির পার্থক্য ব্যাখ্যা করে।
আনবার

4
পরিস্থিতিটি অবাস্তব বলে কী মনে করেন? Stringযুক্ত হওয়ার চেয়ে কনট্যাকটেশন অনেক বেশি ব্যয়বহুল অপারেশন Integers। এটি স্ট্যাটিক্যালি করা (যদি সম্ভব হয়) করা আরও দক্ষ, যা টেস্টটি দেখায়।
rustyx

62

হ্যা পারি. এখানে একটি উদাহরণ যেখানে ফাইনালটি পারফরম্যান্সকে বাড়িয়ে তুলতে পারে:

শর্তসাপেক্ষ সংকলন একটি কৌশল যা লাইন কোডের একটি নির্দিষ্ট শর্তের উপর ভিত্তি করে ক্লাস ফাইলে সংকলিত হয় না। এটি কোনও প্রোডাকশন বিল্ডে টন ডিবাগিং কোড সরিয়ে দিতে ব্যবহার করা যেতে পারে।

নিম্নোক্ত বিবেচনা কর:

public class ConditionalCompile {

  private final static boolean doSomething= false;

    if (doSomething) {
       // do first part. 
    }

    if (doSomething) {
     // do second part. 
    }

    if (doSomething) {     
      // do third part. 
    }

    if (doSomething) {
    // do finalization part. 
    }
}

ডোসমিংথ অ্যাট্রিবিউটকে একটি চূড়ান্ত বৈশিষ্ট্যে রূপান্তরিত করে আপনি সংকলককে বলেছিলেন যে এটি যখনই ডসোমিংথিং দেখে, তখন এটি সংকলন-সময় প্রতিস্থাপনের নিয়ম অনুসারে মিথ্যা দিয়ে প্রতিস্থাপন করা উচিত। সংকলকটির প্রথম পাসটি কোডটিকে এমন কিছুতে পরিবর্তন করে :

public class ConditionalCompile {

  private final static boolean doSomething= false;

    if (false){
       // do first part. 
    }

    if (false){
     // do second part. 
    }

    if (false){
      // do third part. 
    }

    if (false){
    // do finalization part. 

    }
}

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

public class ConditionalCompile {


  private final static boolean doSomething= false;

  public static void someMethodBetter( ) {

    // do first part. 

    // do second part. 

    // do third part. 

    // do finalization part. 

  }
}

এইভাবে কোনও অতিরিক্ত কোড, বা কোনও অপ্রয়োজনীয় শর্তাধীন পরীক্ষণ হ্রাস করা।

সম্পাদনা করুন: উদাহরণ হিসাবে, আসুন নিম্নলিখিত কোডগুলি গ্রহণ করুন:

public class Test {
    public static final void main(String[] args) {
        boolean x = false;
        if (x) {
            System.out.println("x");
        }
        final boolean y = false;
        if (y) {
            System.out.println("y");
        }
        if (false) {
            System.out.println("z");
        }
    }
}

জাভা 8 দিয়ে এই কোডটি সংকলন করার সাথে সাথে javap -c Test.classআমরা পাই:

public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public static final void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: ifeq          14
       6: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: ldc           #22                 // String x
      11: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      14: iconst_0
      15: istore_2
      16: return
}

আমরা নোট করতে পারি যে সংকলিত কোডে কেবলমাত্র চূড়ান্ত নয় এমন চূড়ান্ত রয়েছে x। এটি প্রমান করে যে চূড়ান্ত ভেরিয়েবলগুলি পারফরম্যান্সের উপর প্রভাব ফেলে, কমপক্ষে এই সাধারণ ক্ষেত্রে।


1
@ AsukaszLech আমি চূড়ান্ত কীওয়ার্ড সম্পর্কিত তাদের অধ্যায়ে ওড়িলির একটি বই: হার্ড জাভা থেকে এই বিষয়টি শিখেছি।
mel3kings

15
এই সংকলনের সময়ে অপ্টিমাইজেশনের বিষয়ে কথা বলার অর্থ, বিকাশকারী কম্পাইল সময়ে চূড়ান্ত বুলিয়ান ভেরিয়েবলের ভ্যালু জানে, লেখার পুরো বিন্দুটি যদি প্রথম স্থানে ব্লক হয় তবে এই পরিস্থিতিতে যেখানে আইএফ-শর্তগুলি প্রয়োজনীয় নয় এবং তৈরি হচ্ছে না কোন অনুভূতি? আমার মতে, এমনকি যদি এটি পারফরম্যান্স বাড়িয়ে দেয় তবে এটি প্রথম স্থানে ভুল কোড এবং সংস্থাপকের দায়িত্বে উত্তীর্ণ হওয়ার পরিবর্তে বিকাশকারী নিজেই অনুকূলিত হতে পারেন এবং প্রশ্নটি সাধারণত কোডগুলিতে পারফরম্যান্সের উন্নতি সম্পর্কে জিজ্ঞাসা করতে চায় যেখানে ফাইনাল ব্যবহৃত হয় প্রোগ্রামেটিক বোধ তৈরি করে।
ভবেশ আগরওয়াল

7
এর মূলটি হ'ল মেল 3કિંગগুলি যেমন বলেছে তেমনি ডিবাগিং স্টেটমেন্ট যুক্ত করা। আপনি কোনও প্রোডাকশন বিল্ড করার আগে ভেরিয়েবলটি সরিয়ে ফেলতে পারেন (বা এটি আপনার বিল্ড স্ক্রিপ্টগুলিতে কনফিগার করতে পারেন) এবং বিতরণটি তৈরি হওয়ার পরে স্বয়ংক্রিয়ভাবে সেই কোডটি সমস্ত সরিয়ে ফেলতে পারেন।
আদম

37

আইবিএম-এর মতে - এটি ক্লাস বা পদ্ধতিগুলির জন্য নয়।

http://www.ibm.com/developerworks/java/library/j-jtp04223.html


1
... এবং আইবিএম এর মতে, এটি ক্ষেত্রগুলির জন্য করে : আইবিএম / ডেভেলপ ওয়ার্কস / জাভা / লিবারি / জ-jtp1029/… - এবং একটি সেরা অনুশীলন হিসাবে প্রচার করা হয়।
ফিলজেন

2
"04223" নিবন্ধটি ২০০৩ সালের। এখন প্রায় সতেরো বছর বয়সী। যা ছিল ... জাভা 1.4?
দমতেজ

16

আমি অবাক হয়েছি যে কেউ আসলেই এমন কিছু বাস্তব কোড পোস্ট করেনি যা কমপক্ষে কিছুটা ছোটখাটো পার্থক্য রয়েছে তা প্রমাণ করতে ডি-সংকলিত।

রেফারেন্সের জন্য এটি javacসংস্করণ 8, 9এবং এর বিপরীতে পরীক্ষা করা হয়েছে 10

এই পদ্ধতিটি ধরুন:

public static int test() {
    /* final */ Object left = new Object();
    Object right = new Object();

    return left.hashCode() + right.hashCode();
}

এই কোডটি যেমন রয়েছে তেমন সংকলন করে, ঠিক কখন finalউপস্থিত হত ( final Object left = new Object();) উপস্থিত ছিল ঠিক ঠিক তেমন বাইট কোডটি produces

তবে এটি একটি:

public static int test() {
    /* final */ int left = 11;
    int right = 12;
    return left + right;
}

উত্পাদন:

   0: bipush        11
   2: istore_0
   3: bipush        12
   5: istore_1
   6: iload_0
   7: iload_1
   8: iadd
   9: ireturn

finalউপস্থিত থাকতে ছেড়ে উত্পাদন করে:

   0: bipush        12
   2: istore_1
   3: bipush        11
   5: iload_1
   6: iadd
   7: ireturn

কোডটি বেশ স্ব-বর্ণনামূলক, যদি কোনও সংকলনের সময় ধ্রুবক থাকে তবে এটি সরাসরি অপারেন্ড স্ট্যাকের মধ্যে লোড করা হবে (এটি পূর্ববর্তী উদাহরণের মতো স্থানীয় ভেরিয়েবল অ্যারেতে সংরক্ষণ করা হবে না bipush 12; istore_0; iload_0) - কোন ধরণের অর্থটি তৈরি হয় যেহেতু কেউ এটি পরিবর্তন করতে পারে না।

অন্যদিকে কেন দ্বিতীয় ক্ষেত্রে সংকলকটি উত্পাদন করে না istore_0 ... iload_0তা আমার বাইরে, এটি স্লটটি কোনওভাবেই 0ব্যবহৃত হয় না (এটি ভেরিয়েবলগুলি অ্যারেটি সঙ্কুচিত করতে পারে তবে আমি কিছু অভ্যন্তরীণ বিবরণ অনুপস্থিত হতে পারে) নিশ্চিতভাবে বলুন)

ছোটরা কী করে তা বিবেচনা করে এই জাতীয় একটি অপ্টিমাইজেশন দেখে আমি অবাক হয়েছি javac। আমাদের সবসময় ব্যবহার করা উচিত final? এমনকি আমি একটি JMHপরীক্ষাও লিখতে যাচ্ছি না (যা আমি প্রথম দিকে চেয়েছিলাম), আমি নিশ্চিত যে পার্থক্যটি যথাযথভাবে রয়েছে ns(যদি সম্ভব হয় তবে কিছুটা ক্যাপচার করাও )। এটি কেবলমাত্র সমস্যার কারণ হতে পারে, যখন কোনও আকারের কারণে কোনও পদ্ধতিটি অন্তর্ভুক্ত করা যায় না (এবং ঘোষণা করে finalযে আকারটি কয়েক বাইট দ্বারা সঙ্কুচিত হবে)।

আরও দুটি বিষয় রয়েছে যার দিকে finalনজর দেওয়া দরকার। প্রথমত যখন কোনও পদ্ধতিটি final( JITদৃষ্টিকোণ থেকে ) হয়, তখন এ জাতীয় পদ্ধতিটি মনোমর্ফিক হয় - এবং এগুলি হ'ল এর দ্বারা সর্বাধিক প্রিয়JVM

তারপরে finalউদাহরণস্বরূপ ভেরিয়েবল রয়েছে (এটি অবশ্যই প্রতিটি কনস্ট্রাক্টরে সেট করা উচিত); এগুলি গুরুত্বপূর্ণ কারণ তারা সঠিকভাবে প্রকাশিত রেফারেন্সের গ্যারান্টি দেবে, যেমনটি এখানে কিছুটা স্পর্শ করা হয়েছে এবং ঠিক ঠিক দ্বারা নির্দিষ্ট করে JLS


আমি জাবা 8 (JDK 1.8.0_162) ব্যবহার করে ডিবাগ অপশনগুলি ( javac -g FinalTest.java) ব্যবহার করে কোডটি সংকলন করেছি, কোডটি ব্যবহার করে ডিসকম্পিল করেছি javap -c FinalTest.classএবং একই ফলাফল final int left=12পেয়েছি (এর সাথে , আমি পেয়েছি bipush 11; istore_0; bipush 12; istore_1; bipush 11; iload_1; iadd; ireturn)। সুতরাং হ্যাঁ, উত্পাদিত বাইটকোড প্রচুর কারণগুলির উপর নির্ভরশীল এবং কোনওটি finalপারফরম্যান্সে প্রভাব ফেলছে কিনা তা বলা শক্ত । তবে বাইটকোডটি পৃথক হওয়ার কারণে কিছু পারফরম্যান্সের পার্থক্য থাকতে পারে।
জুলিয়েন ক্রোনেগ


13

আপনি সত্যিই দুটি (কমপক্ষে) বিভিন্ন ক্ষেত্রে জিজ্ঞাসা করছেন:

  1. final স্থানীয় ভেরিয়েবলের জন্য
  2. final পদ্ধতি / ক্লাসের জন্য

জন স্কিটি ইতিমধ্যে 2 টি উত্তর দিয়েছে)। প্রায় 1):

আমি মনে করি না যে এটি কোনও পার্থক্য করে; স্থানীয় ভেরিয়েবলের জন্য, সংকলকটি ভেরিয়েবলটি চূড়ান্ত কিনা তা নির্ধারণ করতে পারে (কেবল এটি একবারে একাধিকবার নির্ধারিত হয়েছে কিনা তা পরীক্ষা করে)। সুতরাং যদি সংকলকটি কেবল একবার বরাদ্দ করা ভেরিয়েবলগুলি অনুকূল করতে চায়, তবে ভেরিয়েবলটি ঘোষিত হয়েছে কিনা তা তা বিবেচ্য finalনয়।

final সুরক্ষিত / পাবলিক বর্গ ক্ষেত্রের জন্য একটি পার্থক্য করতে পারে ; ক্ষেত্রটি একাধিকবার সেট করা হচ্ছে কিনা তা নির্ধারণকারীর পক্ষে এটি নির্ধারণ করা খুব কঠিন, কারণ এটি অন্য শ্রেণীর (যা সম্ভবত লোড করা হয়নি) থেকেও ঘটতে পারে। তবে তারপরেও জেভিএম জনের বর্ণিত কৌশলটি ব্যবহার করতে পারে (আশাবাদীভাবে অনুকূলিত করতে পারে, যদি কোনও শ্রেণি লোড হয় যা ক্ষেত্রটি পরিবর্তন করে তবে প্রত্যাবর্তন করুন)।

সংক্ষেপে, এটির কার্য সম্পাদনে সহায়তা করার কোনও কারণ আমি দেখতে পাচ্ছি না। সুতরাং এই ধরণের মাইক্রো অপ্টিমাইজেশান সাহায্য করার সম্ভাবনা কম। আপনি এটি নিশ্চিত করার জন্য বেঞ্চমার্কিংয়ের চেষ্টা করতে পারেন, তবে আমি সন্দেহ করি এটি একটি পার্থক্য আনবে।

সম্পাদনা:

আসলে, টিমো ওয়েস্টক্যাম্পারের উত্তর অনুসারে কিছু ক্ষেত্রে ক্লাস ফিল্ডগুলির জন্য পারফরম্যান্স উন্নতি final করতে পারে। আমি সংশোধন করেছি.


আমি মনে করি না যে সংকলকটি স্থানীয় ভেরিয়েবলের কতবার নির্ধারিত হয়েছে তা সঠিকভাবে যাচাই করতে পারে: যদি তারপর-অন্যথায় অসংখ্য অ্যাসাইনমেন্টের সাথে স্ট্রাক্ট করা যায়?
gyorgyabraham

1
@ গ্যাব্রাহাম: আপনি যদি কোনও স্থানীয় ভেরিয়েবল হিসাবে ঘোষণা করেন finalযে আপনি এটি দুটিবার না বরাদ্দ করেছেন তা নিশ্চিত করার জন্য সংকলক ইতিমধ্যে এই কেসগুলি পরীক্ষা করে। আমি যতদূর দেখতে পাচ্ছি, একই চেকিং লজিকটি (এবং সম্ভবত এটি) ভেরিয়েবল হতে পারে কিনা তা যাচাই করার জন্য ব্যবহার করা যেতে পারে final
sleske

স্থানীয় ভেরিয়েবলের চূড়ান্ত নেস বাইটকোডে প্রকাশ করা হয় না, সুতরাং জেভিএম এমনকি জানে না যে এটি চূড়ান্ত ছিল
স্টিভ কুও

1
@ স্টিভকুও: বাইটোকোডে এটি প্রকাশ না করা হলেও এটি javacআরও ভালভাবে অনুকূলিত হতে সহায়তা করতে পারে । তবে এটি কেবল জল্পনা।
সলেসকে

1
সংকলকটি স্থানীয় ভেরিয়েবলটি ঠিক একবার বরাদ্দ করা হয়েছে কিনা তা খুঁজে পেতে পারে তবে বাস্তবে এটি ত্রুটি যাচাইয়ের বাইরে নয়। অন্যদিকে, যদি কোনও finalভেরিয়েবল প্রিমিটিভ টাইপ বা প্রকারের হয় Stringএবং তাত্ক্ষণিকভাবে প্রশ্নের উদাহরণের মতো একটি সংকলন-সময় ধ্রুবক সহ নির্ধারিত হয়, সংকলকটিকে অবশ্যই এটি ইনলাইন করতে হবে, কারণ পরিবর্তনশীল স্পেসিফিকেশন অনুসারে একটি সংকলন-সময় ধ্রুবক। তবে বেশিরভাগ ব্যবহারের ক্ষেত্রে কোডটি অন্যরকম দেখাতে পারে তবে স্থানীয় ধরণের পরিবর্তনশীল পারফরম্যান্স অনুযায়ী ধ্রুবকটি ইনলাইনড হয় কিনা তা এখনও কোনও পার্থক্য করে না।
হলগার

6

দ্রষ্টব্য: জাভা বিশেষজ্ঞ নয়

যদি আমি আমার জাভা সঠিকভাবে মনে রাখি তবে চূড়ান্ত কীওয়ার্ড ব্যবহার করে পারফরম্যান্সের উন্নতি করার খুব কম উপায় থাকবে। আমি এটি সর্বদা এটি "ভাল কোড" - ডিজাইন এবং পাঠযোগ্যতার জন্য বিদ্যমান বলে জানি known


1

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


1

প্রকৃতপক্ষে, কিছু ওপেনএল-সম্পর্কিত কোড পরীক্ষা করার সময়, আমি দেখতে পেয়েছি যে একটি ব্যক্তিগত ক্ষেত্রে চূড়ান্ত সংশোধক ব্যবহার করা পারফরম্যান্সকে হ্রাস করতে পারে । এখানে আমি পরীক্ষিত ক্লাসটির শুরু:

public class ShaderInput {

    private /* final */ float[] input;
    private /* final */ int[] strides;


    public ShaderInput()
    {
        this.input = new float[10];
        this.strides = new int[] { 0, 4, 8 };
    }


    public ShaderInput x(int stride, float val)
    {
        input[strides[stride] + 0] = val;
        return this;
    }

    // more stuff ...

এবং শ্যাডারইনপুট শ্রেণীর মধ্যে বিভিন্ন বিকল্পের পারফরম্যান্স পরীক্ষা করতে আমি এই পদ্ধতিটি ব্যবহার করেছি:

public static void test4()
{
    int arraySize = 10;
    float[] fb = new float[arraySize];
    for (int i = 0; i < arraySize; i++) {
        fb[i] = random.nextFloat();
    }
    int times = 1000000000;
    for (int i = 0; i < 10; ++i) {
        floatVectorTest(times, fb);
        arrayCopyTest(times, fb);
        shaderInputTest(times, fb);
        directFloatArrayTest(times, fb);
        System.out.println();
        System.gc();
    }
}

তৃতীয় পুনরাবৃত্তির পরে, ভিএম উত্তাপিত হওয়ার পরে, আমি ধারাবাহিকভাবে চূড়ান্ত মূল শব্দটি ছাড়াই এই পরিসংখ্যানগুলি পেয়েছিলাম :

Simple array copy took   : 02.64
System.arrayCopy took    : 03.20
ShaderInput took         : 00.77
Unsafe float array took  : 05.47

সঙ্গে চূড়ান্ত মূল শব্দ:

Simple array copy took   : 02.66
System.arrayCopy took    : 03.20
ShaderInput took         : 02.59
Unsafe float array took  : 06.24

শ্যাডারইনপুট পরীক্ষার জন্য পরিসংখ্যানগুলি নোট করুন।

আমি ক্ষেত্রগুলি সরকারী বা বেসরকারী বানিয়েছি তা বিবেচ্য নয়।

ঘটনাচক্রে, আরও কিছু বিস্মিত জিনিস আছে। শেদারআইনপুট শ্রেণি চূড়ান্ত কীওয়ার্ড সহ অন্য সমস্ত রূপকে ছাড়িয়ে যায়। এটি লক্ষণীয় বি / সি এটি মূলত একটি শ্রেণীর যা একটি ফ্লোট অ্যারে মোড়ানো, অন্য পরীক্ষাগুলি অ্যারেটি সরাসরি পরিচালনা করে। এই এক খুঁজে বের করতে হবে। শ্যাডারইনপুট এর সাবলীল ইন্টারফেসের সাথে কিছু থাকতে পারে।

এছাড়াও System.arrayCopy লুপের জন্য একটি অ্যারে থেকে অপরটিতে উপাদানগুলি অনুলিপি করার চেয়ে ছোট অ্যারেগুলির জন্য সম্ভবত দৃশ্যত কিছুটা ধীর। এবং sun.misc.Unsafe (সেইসাথে সরাসরি java.nio.FloatBuffer, এখানে দেখানো হয়নি) ব্যবহার করে অসাধারণ অভিনয় করে।


1
আপনি পরামিতিগুলি চূড়ান্ত করতে ভুলে গেছেন। <pre> <কোড> পাবলিক শেদারআইনপুট এক্স (ফাইনাল ইন স্ট্রাইড, ফাইনাল ফ্লোট ভল) {ইনপুট [স্ট্রাইডস [স্ট্রাইড] + 0] = ভাল; এটি ফেরত দিন; experiences </code> </pre> আমার অভিজ্ঞতাগুলিতে কোনও পরিবর্তনশীল বা ফিল্ড ফাইনাল করা প্রকৃতপক্ষে পারফরম্যান্সকে বাড়িয়ে তুলতে পারে।
এন্টিক্রো

1
ওহ, এবং অন্যকেও চূড়ান্ত করে তোলেন: <pre> <কোড> ফাইনাল ইন অ্যারে সাইজ = 10; চূড়ান্ত ভাসা [] এফবি = নতুন ফ্লোট [অ্যারে সাইজ]; (int i = 0; i <arraySize; i ++) {fb [i] = random.nextFloat (); } ফাইনাল ইন টাইমস = 1000000000; (int i = 0; i <10; ++ i) for floatVectorTest (বার, এফবি); অ্যারেকপিটেষ্ট (বার, এফবি); shaderInputTest (বার, fb); DirectFloatArrayTest (বার, এফবি); System.out.println (); System.gc (); । </code> </pre>
এন্টিক্রো

1

চূড়ান্ত (কমপক্ষে সদস্যের ভেরিয়েবল এবং পরামিতিগুলির জন্য) মানুষের পক্ষে বেশি তবে তা মেশিনের জন্য।

যেখানেই সম্ভব ভেরিয়েবলকে ফাইনাল করা ভাল অনুশীলন। আমি চাই জাভা ডিফল্টরূপে "ভেরিয়েবলগুলি" চূড়ান্ত করে এবং পরিবর্তনের অনুমতি দেওয়ার জন্য একটি "মিউটেবল" কীওয়ার্ড পেয়েছিল। অপরিবর্তনীয় ক্লাসগুলি আরও ভাল থ্রেডযুক্ত কোডে নেতৃত্ব দেয় এবং প্রতিটি সদস্যের সামনে "ফাইনাল" সহ একটি ক্লাসে ঝলকানো তাড়াতাড়ি তা পরিবর্তনযোগ্য হিসাবে দেখাবে show

অন্য কেস - আমি @ নন নল / @ নুল টিক চিহ্নগুলি ব্যবহার করতে প্রচুর কোড রূপান্তর করেছি (আপনি বলতে পারেন যে কোনও পদ্ধতি প্যারামিটারটি শূন্য হওয়া উচিত না তবে আইডিই আপনাকে যে কোনও ভেরিয়েবল পাস করে এমন প্রতিটি স্থানে সতর্ক করতে পারে যা আপনি ট্যাগ নেই @ নন-নুল - পুরো জিনিসটি একটি হাস্যকর ডিগ্রীতে ছড়িয়ে পড়ে)। কোনও সদস্যের ভেরিয়েবল প্রমাণ করা অনেক সহজ বা প্যারামিটারটি চূড়ান্ত ট্যাগ করার পরে শূন্য হতে পারে না কারণ আপনি জানেন যে এটি অন্য কোথাও পুনরায় বরাদ্দ দেওয়া হচ্ছে না।

আমার পরামর্শটি হ'ল ডিফল্ট অনুসারে সদস্য এবং পরামিতিগুলির জন্য চূড়ান্ত প্রয়োগের অভ্যাসে প্রবেশ করা, এটি কেবলমাত্র কয়েকটি অক্ষর তবে আপনার কোডিং শৈলীর উন্নতির দিকে ঝুঁকবে যদি অন্য কিছু না হয়।

পদ্ধতি বা ক্লাসগুলির জন্য চূড়ান্ত হ'ল একটি ধারণা, কারণ এটি পুনরায় ব্যবহারের একটি খুব বৈধ ফর্মটিকে অস্বীকার করে এবং পাঠককে সত্যিই বেশি কিছু বলে না। সম্ভবত তারা স্ট্রিং এবং অন্যান্য অভ্যন্তরীণ প্রকারগুলি চূড়ান্ত করে দেওয়ার উপায়টি সম্ভবত আপনি সর্বত্রই সামঞ্জস্যপূর্ণ আচরণের উপর নির্ভর করতে পারেন - এটি প্রচুর বাগগুলি প্রতিরোধ করেছে (যদিও এমন সময় রয়েছে যা আমি স্ট্রিং প্রসারিত করতে পছন্দ করতাম .... ওহ সম্ভাবনার)


0

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

'ফাইনাল' হ'ল একটি বিবৃতি যা আপনি পরিবর্তনশীলকে পরিবর্তন না করার উদ্দেশ্যে অভিহিত করেছেন (অর্থাত্ ভেরিয়েবলটি পৃথক হবে না!)। সংকলক তারপরে আপনি যদি নিজের সীমাবদ্ধতা লঙ্ঘন করেন তবে অভিযোগ করে আপনাকে সাহায্য করতে পারে।

আমি এই অনুভূতিটি শেয়ার করি যে সনাক্তকারীরা (আমি দুঃখিত, আমি কেবল কোনও ভিন্ন-ভিন্ন বিষয়টিকে 'ভেরিয়েবল' বলতে পারি না) ডিফল্টরূপে চূড়ান্ত হত এবং আপনাকে স্পষ্টভাবে বলতে হয়েছিল যে তারা ভেরিয়েবল ছিল। তবে এই বলে যে, আমি সাধারণত স্থানীয় ভেরিয়েবলগুলিতে 'চূড়ান্ত' ব্যবহার করি না যেগুলি আরম্ভ করা হয় এবং কখনই বরাদ্দ করা হয় না; এটা খুব গোলমাল মনে হচ্ছে।

(আমি সদস্য ভেরিয়েবলগুলিতে চূড়ান্ত ব্যবহার করি)


-3

চূড়ান্ত হিসাবে ঘোষিত সদস্যগণ পুরো প্রোগ্রাম জুড়ে উপলব্ধ থাকবেন কারণ ননফাইনাল সদস্যদের বিপরীতে, যদি এই সদস্যরা প্রোগ্রামে ব্যবহার না করে থাকেন তবে তাদের আবর্জনা সংগ্রাহকরা তাদের যত্ন নেবেন না যাতে খারাপ স্মৃতি পরিচালনার কারণে পারফরম্যান্স সমস্যার কারণ হতে পারে।


2
এ কেমন বাজে কথা? আপনি কি মনে করেন যে এই ঘটনাটি কেন আপনার কোনও উত্স আছে?
জে দো

-4

final কীওয়ার্ডটি জাভাতে পাঁচটি উপায়ে ব্যবহার করা যেতে পারে।

  1. একটি ক্লাস চূড়ান্ত হয়
  2. একটি রেফারেন্স ভেরিয়েবল চূড়ান্ত
  3. একটি স্থানীয় পরিবর্তনশীল চূড়ান্ত হয়
  4. একটি পদ্ধতি চূড়ান্ত হয়

একটি শ্রেণি চূড়ান্ত: একটি শ্রেণি চূড়ান্ত মানে আমাদের বাড়ানো যায় না বা উত্তরাধিকার মানে উত্তরাধিকার সম্ভব হয় না।

একইভাবে - একটি অবজেক্ট চূড়ান্ত: কিছু সময় আমরা অবজেক্টের অভ্যন্তরীণ স্থিতিটি পরিবর্তন করি না সুতরাং এই জাতীয় ক্ষেত্রে আমরা অবজেক্টটি চূড়ান্ত অবজেক্টটি নির্দিষ্ট করতে পারি ob অবজেক্টের চূড়ান্ত অর্থ পরিবর্তনশীলও চূড়ান্ত নয়।

একবার রেফারেন্স ভেরিয়েবল চূড়ান্ত হয়ে গেলে, এটি অন্য অবজেক্টে পুনঃসাইন করা যাবে না। যতক্ষণ না এর ক্ষেত্রগুলি চূড়ান্ত না হয় ততক্ষণ অবজেক্টের বিষয়বস্তু পরিবর্তন করতে পারে


2
"অবজেক্ট চূড়ান্ত" দ্বারা আপনি বোঝানো "অবজেক্টটি অপরিবর্তনীয়"।
গাইর্জ্যাব্রাহাম

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