# ifdef # ifndef w Javie

Wątpię, czy istnieje sposób, aby Warunki kompilacji w Javie jak #ifdef #ifndef w C++.

Mój problem polega na tym, że mam algorytm napisany w Javie, a ja mam inny czas działania niż ten algorytm. Chcę więc zmierzyć, ile czasu oszczędzam, gdy każda poprawa jest używana.

W tej chwili mam zestaw zmiennych boolowskich, które są używane do decydowania w czasie działania, które ulepszenie powinno być używane, a które nie. Ale nawet testowanie tych zmiennych wpływa na całkowity czas pracy.

Chcę więc dowiedzieć się, jak w czasie kompilacji zdecydować, które części programu powinny być skompilowane i użyte.

Czy ktoś wie jak to zrobić w Javie. A może ktoś wie, że nie ma takiej drogi (to też by się przydało).

Author: jldupont, 2009-11-29

7 answers

private static final boolean enableFast = false;

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

Warunki takie jak pokazane powyżej są oceniane podczas kompilacji. If instead you use this

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

Wtedy wszelkie warunki zależne od enableFast będą oceniane przez kompilator JIT. Koszty na to są znikome.

 118
Author: Mark Thornton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-08 07:51:34

Javac nie wyświetli skompilowanego kodu, który jest nieosiągalny. Użyj ostatecznej zmiennej ustawionej na stałą wartość dla #define i normalnej instrukcji if dla #ifdef.

Możesz użyć javap, aby udowodnić, że nieosiągalny kod nie jest zawarty w pliku klasy wyjściowej. Na przykład rozważ następujący kod:

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 podaje następujące wyjście, wskazując, że tylko jedna z dwóch ścieżek została skompilowana (a instrukcja if nie była):

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
 41
Author: Phil Ross,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-28 23:36:07

Myślę, że znalazłem rozwiązanie, jest o wiele prostsze.
Jeśli zdefiniuję zmienne logiczne za pomocą modyfikatora "final" kompilator Java sam rozwiązuje problem. Ponieważ z góry wie, jaki byłby wynik badania tego stanu. Na przykład ten kod:

    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++;
    }
Działa na moim komputerze około 3 sekund.
A ten
    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++;
    }
Trwa około 1 sekundy. W tym samym czasie ten kod zajmuje
    int j=0;
    for(int i=0;i<1000000000;i++){
        j++;
    }
 11
Author: jutky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-19 23:27:37

Nigdy go nie używałem, ale to istnieje

JCPP jest kompletnym, zgodnym, samodzielna, czysta implementacja Javy preprocesora C. Jest przeznaczony być użytecznym dla osób piszących w stylu C kompilatorów w Javie przy użyciu takich narzędzi jak sablecc, antlr, JLex, CUP i tak naprzód. Projekt ten został wykorzystany aby pomyślnie przetworzyć wiele z kod źródłowy biblioteki GNU C. Jako wersji 1.2.5, może również preproces Apple Objective C biblioteka.

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

 2
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-28 21:40:53

Jeśli naprawdę potrzebujesz kompilacji warunkowej i używasz Ant, możesz być w stanie przefiltrować swój kod i wykonać w nim wyszukiwanie i zamianę.

Na przykład: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html

W ten sam sposób można na przykład napisać filtr, który zastąpi LOG.debug(...); na /*LOG.debug(...);*/. To i tak wykonywałoby się szybciej niż if (LOG.isDebugEnabled()) { ... } rzeczy, nie wspominając o byciu bardziej zwięzłym w tym samym czasie.

Jeśli używasz Maven , istnieje podobna cecha opisana proszę..

 2
Author: rustyx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:31

Użyć wzorca fabrycznego, aby przełączać się między implementacjami klasy?

Czas tworzenia obiektu nie może być teraz problemem, prawda? Kiedy uśrednione przez długi okres czasu, największy składnik czasu spędzonego powinien być teraz w głównym algorytmie, czyż nie?

Ściśle mówiąc, nie potrzebujesz preprocesora do robienia tego, co chcesz osiągnąć. Są najprawdopodobniej inne sposoby spełnienia twoich wymagań niż ten, który oczywiście zaproponowałem.

 1
Author: jldupont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-28 21:49:10
final static int appFlags = context.getApplicationInfo().flags;
final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0
 0
Author: alicanbatur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-21 12:45:22