জাভাতে #ifdef #ifndef


106

আমার সন্দেহ হয় জাভাতে সি ++ তে #ifdef #ifndef এর মতো কম্পাইল-টাইম শর্ত তৈরি করার কোনও উপায় আছে কিনা।

আমার সমস্যাটি হ'ল জাভাতে একটি অ্যালগরিদম লেখা আছে এবং আমার চলমান সময়টি সেই অ্যালগরিদমে উন্নতি করে। সুতরাং আমি প্রতিটি উন্নতি ব্যবহৃত হলে আমি কতটা সময় সাশ্রয় করি তা পরিমাপ করতে চাই।

এই মুহূর্তে আমার কাছে বুলিয়ান ভেরিয়েবলগুলির একটি সেট রয়েছে যা চলমান সময়টি ঠিক করতে ব্যবহৃত হয় যা উন্নত করা উচিত এবং কোনটি নয়। এমনকি সেই চলকগুলি পরীক্ষা করে মোট চলমান সময়কে প্রভাবিত করে।

সুতরাং আমি সংকলনকালে প্রোগ্রামের কোন অংশটি সংকলন এবং ব্যবহার করা উচিত তা সিদ্ধান্ত নেওয়ার একটি উপায় জানতে চাই।

কেউ কি জাভাতে এটি করার কোনও উপায় জানেন। বা হতে পারে যে কেউ জানেন যে এরকম কোনও উপায় নেই (এটি কার্যকরও হবে)।

উত্তর:


126
private static final boolean enableFast = false;

// ...
if (enableFast) {
  // This is removed at compile time
}

উপরের মতো প্রদর্শিত শর্তগুলি সংকলন সময়ে মূল্যায়ন করা হয়। পরিবর্তে আপনি যদি এটি ব্যবহার

private static final boolean enableFast = "true".equals(System.getProperty("fast"));

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


আমার এই সমাধানটি আরও ভাল। আমি যখন প্রিসেটযুক্ত বাইরের মান দিয়ে ভেরিয়েবলগুলি আরম্ভ করার চেষ্টা করতাম তখন চলমান সময়টি 3 সেকেন্ডে ফিরে যায়। তবে আমি যখন ভেরিয়েবলগুলি স্থিতিক শ্রেণীর ভেরিয়েবল হিসাবে বর্ণনা করি (এবং কোনও ফাংশন স্থানীয় ভেরিয়েবল নয়) চলমান সময়টি 1 সেকেন্ডে ফিরে আসে। সাহায্যের জন্য ধন্যবাদ.
জটকি

6
আইআইআরসি, এটি জাভাতে একটি জেআইটি সংকলক হওয়ার আগেও কাজ করেছিল। javacআমার মনে হয় কোডটি সরানো হয়েছিল । এটি তখনই কাজ করেছিল যদি (বলুন) এর জন্য অভিব্যক্তিটি enableFastএকটি সংকলন সময় ধ্রুবক প্রকাশ ছিল।
স্টিফেন সি

2
হ্যাঁ, তবে এই শর্তসাপেক্ষ অবশ্যই একটি পদ্ধতির মধ্যে থাকতে হবে, তাই না? আমরা সেট করতে চাই এমন একটি প্রাইভেট স্ট্যাটিক ফাইনাল স্ট্রিংগুলির একটি গুচ্ছ রয়েছে সে ক্ষেত্রে কী হবে। (যেমন সার্ভার ইউআরএলগুলির একটি সেট যা উত্পাদন বনাম স্টেজিংয়ের জন্য আলাদাভাবে সেট করা আছে)
টমউইপ্পল

3
@ টমউইপ্পল: সত্য, প্লাস এটি আপনাকে এর মতো কিছু করতে দেয় না: private void foo(#ifdef DEBUG DebugClass obj #else ReleaseClass obj #endif )
জোনকো

3
আমদানি সম্পর্কে কী (উদাহরণস্বরূপ, ক্লাসপথ সম্পর্কিত)?
n611x007

44

জাভ্যাক সঙ্কলিত কোড সংকলিত কোড আউটপুট দেবে না। আপনার জন্য একটি ধ্রুবক মান একটি চূড়ান্ত পরিবর্তনশীল সেট #defineএবং এর জন্য একটি সাধারণ ifবিবৃতি ব্যবহার করুন #ifdef

আপনি না পৌঁছনযোগ্য কোডটি আউটপুট ক্লাস ফাইলে অন্তর্ভুক্ত নেই তা প্রমাণ করতে আপনি জাভাপ ব্যবহার করতে পারেন। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি বিবেচনা করুন:

public class Test
{
   private static final boolean debug = false;

   public static void main(String[] args)
   {
       if (debug) 
       {
           System.out.println("debug was enabled");
       }
       else
       {
           System.out.println("debug was not enabled");
       }
   }
}

javap -c Test নিম্নলিখিত আউটপুট দেয়, ইঙ্গিত করে যে দুটি পাথের মধ্যে একটিতে কেবল সংকলন করা হয়েছিল (এবং যদি বিবৃতিটি ছিল না):

public static void main(java.lang.String[]);
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #3; //String debug was not enabled
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return

2
এই জাভাকটি নির্দিষ্ট, বা এই আচরণটি আসলে জেএলএস দ্বারা নিশ্চিত?
পেসারিয়ার

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

12

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

    boolean flag1 = true;
    boolean flag2 = false;
    int j=0;
    for(int i=0;i<1000000000;i++){
        if(flag1)
            if(flag2)
                j++;
            else
                j++;
        else
            if(flag2)
                j++;
            else
                j++;
    }

আমার কম্পিউটারে প্রায় 3 সেকেন্ড চলে।
এবং এটি

    final boolean flag1 = true;
    final boolean flag2 = false;
    int j=0;
    for(int i=0;i<1000000000;i++){
        if(flag1)
            if(flag2)
                j++;
            else
                j++;
        else
            if(flag2)
                j++;
            else
                j++;
    }

প্রায় 1 সেকেন্ড চলে। এই কোডটি একই সময় নেয়

    int j=0;
    for(int i=0;i<1000000000;i++){
        j++;
    }

1
সেটা মজাদার. মনে হচ্ছে জেআইটি ইতিমধ্যে শর্তসাপেক্ষ সংকলন সমর্থন করে! এই ফাইনালগুলি অন্য শ্রেণিতে বা অন্য কোনও প্যাকেজে থাকলে কী কাজ করে?
জোয়েটউইডল

গ্রেট! তারপরে আমি বিশ্বাস করি এটি অবশ্যই রানটাইম অপ্টিমাইজেশন হতে হবে, কোডটি আসলে সংকলন-সময় ছিনিয়ে নেওয়া হচ্ছে না। আপনি যতক্ষণ না একজন পরিপক্ক ভিএম ব্যবহার করেন ততক্ষণ তা ঠিক।
জোয়েটউইডল

@ জোয়েটউইডল, কীওয়ার্ড হ'ল "যতক্ষণ আপনি" একজন পরিপক্ক ভিএম ব্যবহার করেন।
পেসারিয়ার

2

এটি কখনও ব্যবহার করা হয়নি, তবে এটি বিদ্যমান

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

http://www.anarres.org/projects/jcpp/


1
আমি নিশ্চিত নই যে এটি আমার প্রয়োজন অনুসারে। আমার কোড জাভাতে লেখা আছে। হতে পারে আপনি আমাকে তাদের উত্সগুলি পেতে এবং আমার কোডটি প্রেরোসেস করার জন্য তাদের ব্যবহার করার জন্য প্রস্তাব দিচ্ছেন?
জটকি

2

আপনার যদি সত্যই শর্তসাপেক্ষ সংকলন প্রয়োজন হয় এবং আপনি পিঁপড়া ব্যবহার করেন , আপনি আপনার কোডটি ফিল্টার করতে এবং এতে একটি অনুসন্ধান-এবং-প্রতিস্থাপন করতে সক্ষম হতে পারেন।

উদাহরণস্বরূপ: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html

একই পদ্ধতিতে আপনি, উদাহরণস্বরূপ, প্রতিস্থাপন করার জন্য একটি ফিল্টার লিখতে পারেন LOG.debug(...);সঙ্গে/*LOG.debug(...);*/ । এটি এখনও স্টাফের চেয়ে দ্রুত if (LOG.isDebugEnabled()) { ... }সম্পাদন করবে, একই সাথে আরও সংক্ষিপ্ত হওয়ার কথা উল্লেখ করা উচিত নয়।

আপনি যদি মাভেন ব্যবহার করেন তবে এখানে বর্ণিত অনুরূপ বৈশিষ্ট্য রয়েছে


2

ম্যানিফোল্ড একটি সম্পূর্ণ সংহত জাভা প্রিপ্রোসেসর সরবরাহ করে (কোনও বিল্ড স্টেপ বা উত্পন্ন উত্স নেই)। এটি একচেটিয়াভাবে শর্তসাপেক্ষ সংকলনকে লক্ষ্যবস্তু করে এবং সি-স্টাইল নির্দেশাবলী ব্যবহার করে।

ম্যানিফোল্ডের জাভা প্রিপ্রসেসর


1

কোনও শ্রেণীর প্রয়োগের মধ্যে স্যুইচ করতে কারখানা প্যাটার্নটি ব্যবহার করবেন?

অবজেক্ট তৈরির সময়টি কি এখন উদ্বেগ হতে পারে না? দীর্ঘ সময় ধরে চলাকালীন গড় গড়ে যখন সময় কাটায় তখন সবচেয়ে বড় অংশটি মূল অ্যালগরিদমে থাকা উচিত এখন তাই না?

কড়া কথায় বলতে গেলে, আপনি যা অর্জন করতে চান তা করার জন্য আপনার সত্যিকার অর্থে প্রিপ্রোসেসর প্রয়োজন নেই। আমি অবশ্যই প্রস্তাবিত প্রস্তাবের চেয়ে আপনার প্রয়োজনীয়তা পূরণের সম্ভবত অন্যান্য উপায় রয়েছে।


পরিবর্তনগুলি খুব সামান্য। অনুরোধ করা ফলাফলটি পুনরায় পুনর্নির্মাণের পরিবর্তে অগ্রিম জানতে কিছু শর্ত পরীক্ষা করার মতো। সুতরাং ফাংশনটিতে কলের ওভারহেডটি আমার পক্ষে উপযুক্ত নয়।
জটকি

0
final static int appFlags = context.getApplicationInfo().flags;
final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.