Re[4]: C# .NET vs Java 1.5
От: Alexandro Россия  
Дата: 26.12.06 23:48
Оценка:
Здравствуйте, GNUzaurus, Вы писали:

GNU>Здравствуйте, Alexandro, Вы писали:


G_>>>>Что на ваш взгляд является главным недостатком Java?

GNU>>> Сам факт её существования.

A>>Судя по высказываниям, автор не утрудил себя даже поверхностным обзором java.


GNU> Смешное ты существо. Я под JVM около десятка разнообразных компиляторов написал. Для Java я писал source->source трансляторы и системы статического анализа кода. Я, в отличии от тебя, малограмотного, очень даже хорошо знаю, о чём говорю.


Я не опущусь до оскорбления таких ничтожеств как ты. Закончил.
С уважением,
Александр.
icq: 118852038
Re[6]: C# .NET vs Java 1.5
От: aka50 Россия  
Дата: 27.12.06 07:15
Оценка:
Здравствуйте, Alexandro, Вы писали:

A>Здравствуйте, GNUzaurus, Вы писали:


GNU>> Например, делегаты (потянет только с огромнейшей потерей производительности).

A> делегаты = интерфейс + анонимный класс. где тут потеря производительности?
Это будет не совсем то. Есть даже RFE на его реализацию, и вроде как InProgress.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4191243

GNU>> Про наличие отсутствия хвостовых вызовов в убогонькой JVM так же и напоминать как-то неудобно, это очевидная и всем известная засада.

A>Каким образом должны хвостовые вызовы лежать в jvm? Очень интересно.
Тоже есть RFE. Там же можно прочитать про сложности реализации. (например в случае с security).
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4726340
Re[7]: C# .NET vs Java 1.5
От: Alexandro Россия  
Дата: 27.12.06 08:28
Оценка: +1
Здравствуйте, aka50, Вы писали:

GNU>>> Например, делегаты (потянет только с огромнейшей потерей производительности).

A>> делегаты = интерфейс + анонимный класс. где тут потеря производительности?
A>Это будет не совсем то. Есть даже RFE на его реализацию, и вроде как InProgress.
A>http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4191243
Опять же, возможна реализация delegate — эквивалентной функциональности в рамках jvm.

GNU>>> Про наличие отсутствия хвостовых вызовов в убогонькой JVM так же и напоминать как-то неудобно, это очевидная и всем известная засада.

A>>Каким образом должны хвостовые вызовы лежать в jvm? Очень интересно.
A>Тоже есть RFE. Там же можно прочитать про сложности реализации. (например в случае с security).
A>http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4726340
Согласен, хотя в IBM JVM эта фича реализована. здесь
Автор же говорил, что реализация подобных фич не возможна.

Если вернуться к предыдущей теме, в jvm невозможна реализация некоторых security-аспектов, как это сделано в .NET. Просто security в java реализована по другому.
С уважением,
Александр.
icq: 118852038
Re[5]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 09:39
Оценка:
Здравствуйте, Андрей Хропов, Вы писали:

АХ>В простоте и эффективности реализации других языков. Возьмем к примеру Python. Jython медленее CPython, а IronPython наоборот, почти в 2 раза быстрее. Есть ли в Java аналоги System.CodeDom и System.Reflection.Emit?


Есть в Java6 compiler API javadoc
Если нужно — можно байткод напрямую генерировать и загружать.

С Python, думаю, опятьже дело в некорректных тестах (см ниже).

N>>Гораздо более интересные языки чем C# держит и ничего (Scala)

АХ>Ну, во-первых Scala бывает весьма ощутимо тормозит:
АХ>[Benchmark] Встроенный while vs макросы vs замыкания на Scala
Автор: Андрей Хропов
Дата: 26.11.06


Бенчмарк, как всегда, некорректен Не видел еще ни одного бенчмарка, который адепты C# написали бы корректно для Java или ее производных. В данном случае, не учтено время, которое тратит компилятор byte code -> native code. Вернее, оно не вынесено за рамки измерений.

Как минимум, нужно вставлять -Xcomp -Xbatch и результаты будут в разы лучше.

Хотя, именно в этом случае, просто наткнулись на баг в server JVM плюс то, что компилятор Scala не использует встроенный boolean тип.

АХ>

АХ>We haven't yet gone very far into evaluating those thingies
АХ>(nemerle is dotnet and dotnet offers very far reaching possibilities to
АХ>emit code at runtime
, Java is a bit clumsy and middle-ages in that respect)


Ну, это уже не актуально с появлением compiler API.

АХ>Нет, MS учел уроки Java и создал более технологически совершенный .NET. Я не фанат MS и мне больше нравится то что Java под GPL, но тем не менее это так. И практически во всех тестах MS.NET быстрее Java (здесь писал в ФП).


Все эти т.н. "тесты" либо не учитывают то, что в начале работы происходит компиляция в native code, либо запускаются на client JVM, либо содержат другие грубые ошибки. Если все аккуратно и правильно сделать, то разницу можно увидеть только в конкретных местах, где нечто реализовано существенно по разному.

Например, примитивные типы данных работают быстрее в Java т.к. это не value типы, а отдельная сущность. А в некоторых случаях микробенчмарк можно завязать на value типы и он будет быстрее в .NET.

Или вот в последнем JDK сделали lock elimination/coalesce с помощью escape analysis. Теперь легко можно будет сделать бенчмарк в котором на синхронизации Java будет на порядок быстрее.

Из того, что я еще могу вспомнить — в Java гораздо более продвинутая memory model, которая позволяет компилятору делать очень много оптимизаций и собственно hotspot в то время как основную компиляцию в bytecode .NET делает один раз.

Короче, еще раз, по большей части песни о немеряном технологическом приемуществе .NET VM над JVM это чистый маркетинг. Корректный микробенчмарк сделать и запустить на JVM не так просто, но, она для этого и не предназначена.
Re[5]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 10:07
Оценка:
Здравствуйте, GNUzaurus, Вы писали:

GNU> В JVM нет хвостовой рекурсии. В .NET есть. В JVM нет структур, явно выделяемых на стеке — в .NET есть. В JVM есть лимит на размер методов — явно следующий из привязки к модели разработки на убогом язычке Java — в .NET такого предела нет.


И это ты называешь технологическим приемуществом? Собственно, кроме хвостовой рекурсии ни одного более менее серьезного пункта. Хотя, это тоже вполне решаемый вопрос, если бы кому-то она была бы всерьез нужна — давно бы сделали.

Размер методов — стыдно вообще об этом упомянать, обходится элементарно, а stack allocation уже скоро будет в Sun JVM и уже есть в некоторых JVM, например, в Excelsior Jet. Причем, это будет прозрачно для программиста, не нужно будет использовать разные сущности для того, чтобы добится аллокации на стеке.

Если так подходить, то, у JVM есть свои технологические приемущества, актуальные для императивных языков — в Java есть примитивные типы данных, более эффективные чем структуры, в Java есть escape analysis, в Java есть hotspot машина, в Java есть быстрый biased locking и т.д.
Re[6]: C# .NET vs Java 1.5
От: Андрей Хропов Россия  
Дата: 27.12.06 11:42
Оценка:
Здравствуйте, n0name2, Вы писали:

N>Здравствуйте, Андрей Хропов, Вы писали:


АХ>>В простоте и эффективности реализации других языков. Возьмем к примеру Python. Jython медленее CPython, а IronPython наоборот, почти в 2 раза быстрее. Есть ли в Java аналоги System.CodeDom и System.Reflection.Emit?


N>Есть в Java6 compiler API javadoc

N>Если нужно — можно байткод напрямую генерировать и загружать.

Ну это в общем-то не слишком далеко ушло от

Runtime.getRuntime().exec("javac myprogram.java");


К тому же
1) Это только для Java. Для других языков пользы от этого 0.
2)

Package javax.tools Description

Provides interfaces for tools which can be invoked from a program, for example, compilers.

These interfaces and classes are required as part of the Java™ Platform, Standard Edition (Java SE), but there is no requirement to provide any tools implementing them.
...

There is no requirement for a compiler at runtime.


(здесь)

N>С Python, думаю, опятьже дело в некорректных тестах (см ниже).

Ну да, все тесты у нас у всех некорректные .

N>>>Гораздо более интересные языки чем C# держит и ничего (Scala)

АХ>>Ну, во-первых Scala бывает весьма ощутимо тормозит:
АХ>>[Benchmark] Встроенный while vs макросы vs замыкания на Scala
Автор: Андрей Хропов
Дата: 26.11.06


N>Бенчмарк, как всегда, некорректен Не видел еще ни одного бенчмарка, который адепты C# написали бы корректно для Java или ее производных.

Ну давай изложи свое видение как должно быть корректно. Не супертюнинг конкретной VM под конкретный бенчмарк (хотя все равно подозреваю что быстрее .NET не будет), а общие опции.

N> В данном случае, не учтено время, которое тратит компилятор byte code -> native code. Вернее, оно не вынесено за рамки измерений.

Как это не вынесено? Я вынес. Там замеряется время внутри. Более того, функция также вызывается и до измерения.

N>Как минимум, нужно вставлять -Xcomp -Xbatch и результаты будут в разы лучше.

1) Это нестандартные флаги и не во всех VM они есть:

У меня стоит HotSpot:
D:\>java1 -version
java version "1.5.0_08"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_08-b03)
Java HotSpot(TM) Client VM (build 1.5.0_08-b03, mixed mode)

и JRockit
D:\>java -version
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
BEA JRockit(R) (build R26.4.0-63-63688-1.5.0_06-20060626-2259-win-ia32, )


у HotSpot есть только -Xbatch
D:\>java1 -X
    -Xmixed           mixed mode execution (default)
    -Xint             interpreted mode execution only
    -Xbootclasspath:<directories and zip/jar files separated by ;>
                      set search path for bootstrap classes and resources
    -Xbootclasspath/a:<directories and zip/jar files separated by ;>
                      append to end of bootstrap class path
    -Xbootclasspath/p:<directories and zip/jar files separated by ;>
                      prepend in front of bootstrap class path
    -Xnoclassgc       disable class garbage collection
    -Xincgc           enable incremental garbage collection
    -Xloggc:<file>    log GC status to a file with time stamps
    -Xbatch           disable background compilation
    -Xms<size>        set initial Java heap size
    -Xmx<size>        set maximum Java heap size
    -Xss<size>        set java thread stack size
    -Xprof            output cpu profiling data
    -Xfuture          enable strictest checks, anticipating future default
    -Xrs              reduce use of OS signals by Java/VM (see documentation)
    -Xcheck:jni       perform additional checks for JNI functions
    -Xshare:off       do not attempt to use shared class data
    -Xshare:auto      use shared class data if possible (default)
    -Xshare:on        require using shared class data, otherwise fail.


У JRockit таких опций не вижу
D:\>java -X
    -Xbootclasspath:<directories and zip/jar files separated by :>
              set search path for bootstrap classes and resources
    -Xbootclasspath/a:<directories and zip/jar files separated by :>
              append to end of bootstrap class path
    -Xbootclasspath/p:<directories and zip/jar files separated by :>
              prepend in front of bootstrap class path
    -Xgcprio:[throughput|pausetime|deterministic]
              sets prio for the gc-system
                  throughput    optimizes the gc-behavior to achieve optimal
                                throughput (initially starts off with
                                single-spaced parallel GC mode but may switch
                                to other GC modes dynamically during runtime)
                  pausetime     optimizes the gc-behavior to achieve minimal
                                pause times (initially starts off with
                                single-spaced concurrent GC mode but may switch
                                to other GC modes dynamically during runtime)
                  deterministic optimizes the gc-behavior to ensure extremely
                                short pause times and limit the total number of
                                those pauses within a prescribed window (this
                                feature requires a valid license)
    -Xgc:[singlecon|gencon|parallel]
              used to set a static garbage collector
              will override the -Xgcprio option
                  singlecon     use the single-spaced concurrent garbage
                                collector algorithm (default in client mode)
                  gencon        use the generational concurrent
                                garbage collector algorithm
                  parallel      use the single-spaced parallel
                                garbage collector algorithm
                                (default in server mode)
    -Xms<size>[g|G|m|M|k|K]
              sets the initial Java heap size (ms)
                  server mode:  the default value is 25% of the amount
                                of free physical memory in the system
                                up to 64 MB with a minimum of 8 MB (default)
                  client mode:  the default value is 25% of the amount
                                of free physical memory in the system
                                up to 16 MB with a minimum of 8 MB
    -Xmx<size>[g|G|m|M|k|K]
              sets the maximum Java heap size (mx)
                  server mode:  the default value is the smallest of 75% of
                                physical memory and 1536 MB (default)
                  client mode:  the default value is the smallest of 75% of
                                physical memory and 64 MB
    -Xns<size>[g|G|m|M|k|K]
              sets the initial Java nursery size for generational collectors
                  server mode:  the default value is 10 MB per (default)
                  client mode:  the default value is 2 MB
    -Xss<size>[g|G|m|M|k|K]
              set initial stack size
    -Xpausetarget=<optimal_pause_time>[ms|s]
              JRockit will optimize the pause time to the given target,
              uses -Xgcprio:pausetime
                  ms            pause time specified in milliseconds (default)
                  s             pause time specified in seconds
    -Xnoclassgc
              disable class garbage collection
    -Xgcpause
              print pause times caused by the garbage collector
    -Xgcreport
              write extensive memory report at end of run
    -Xdebug
              enables debugging support in the VM
    -Xrun<library>
              loads and runs a library
    -Xjvmpi:[<argument1>=<value1>[,<argumentN>=<valueN>]]
              enable/disable groups of jvmpi events when running jvmpi
                  entryexit     (default on)
                  allocs        (default on)
                  monitors      (default on)
    -Xmanagement
              enable the management server needed by the
              JRockit Console
    -Xnoopt
              do not optimize code
    -Xstrictfp
              always use strict floating point calculations
    -Xverify
              do full bytecode verification
    -Xnohup or -Xrs
              JRockit will not process CTRL_LOGOFF_EVENT or SIGHUP events
    -Xverbose[:memory|load|jni|cpuinfo|codegen|opt]
              enable verbose output
    -Xverboselog:<file>
              log verbose output to a file
    -Xverbosetimestamp
              adds a timestamp to the verbose printout


2) попробовал HotSpot с -Xcomp -Xbatch (-Xcomp оказывается работает, правда об этом в опциях ни слова ).
Небольшое ускорение в обычном цикле (все равно ~ в 8 раз медленее MS.NET):

Simple do-while: 1352
Repeat until: 4006


АХ>>

АХ>>We haven't yet gone very far into evaluating those thingies
АХ>>(nemerle is dotnet and dotnet offers very far reaching possibilities to
АХ>>emit code at runtime
, Java is a bit clumsy and middle-ages in that respect)


N>Ну, это уже не актуально с появлением compiler API.

см. выше

АХ>>Нет, MS учел уроки Java и создал более технологически совершенный .NET. Я не фанат MS и мне больше нравится то что Java под GPL, но тем не менее это так. И практически во всех тестах MS.NET быстрее Java (здесь писал в ФП).


N>Все эти т.н. "тесты" либо не учитывают то, что в начале работы происходит компиляция в native code, либо запускаются на client JVM, либо содержат другие грубые ошибки.

В моих тестах замер делается внутри (т.е. время на старт не учитывается), запускал на разных VM и -server и -client (об этом тоже писал), причем не всегда -server лучше. То что HotSpot иногда вылетает в интерпретацию — так это его реальные условия работы: все честно. Про другие грубые ошибки прошу поподробнее.

N> Если все аккуратно и правильно сделать, то разницу можно увидеть только в конкретных местах, где нечто реализовано существенно по разному.


N>Например, примитивные типы данных работают быстрее в Java т.к. это не value типы, а отдельная сущность.

Это как это они быстрее value типов ? Примеры давай.

N> А в некоторых случаях микробенчмарк можно завязать на value типы и он будет быстрее в .NET.


N>Или вот в последнем JDK сделали lock elimination/coalesce с помощью escape analysis. Теперь легко можно будет сделать бенчмарк в котором на синхронизации Java будет на порядок быстрее.

ссылка, пример?

N>Из того, что я еще могу вспомнить — в Java гораздо более продвинутая memory model,

А чем это она так особо продвинутая?

N> которая позволяет компилятору делать очень много оптимизаций и собственно hotspot в то время как основную компиляцию в bytecode .NET делает один раз.

HotSpot и сам ресурсы отъедает, так что на практике один хрен, а подчас даже хуже (может улететь в интерпретацию).
Но в принципе да, подход неплохой.

N>Короче, еще раз, по большей части песни о немеряном технологическом приемуществе .NET VM над JVM это чистый маркетинг.

Да оно не немеряное, но некоторое есть.

N> Корректный микробенчмарк сделать и запустить на JVM не так просто, но, она для этого и не предназначена.

Во-во. Почему-то под .NET и без танцев с бубнами все несколько быстрее.

P.S. Я не адепт C# и вообще на нем писал довольно мало.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 11:50
Оценка:
Здравствуйте, Alexandro, Вы писали:

GNU>> Например, большие методы. Например, делегаты (потянет только с огромнейшей потерей производительности). Ну про INTPTN и нативные вызовы я и вовсе промолчу.

A>большие методы прекрасно разделяются компилятором на мелкие.

Ха. Ха ха. Разделяются. Только на фиг мне это надо? Мне нужен один большой метод. С БЫСТРЫМИ переходами внутри. Если бы вы были немного грамотнее и знали бы, что такое FSM, то понимали бы, какую чушь вы несете.

A> делегаты = интерфейс + анонимный класс. где тут потеря производительности?


Там и потеря, что в дотнете делегат содержит указатель на функцию. Прежде чем вещать с умным видом — измерил бы сам. Я — измерял разницу в производительности, знаю, о чем говорю.

A> INTPTN — каюсь, не знаю что это. и гугл не знает. Нативные вызовы?


Указатель на функцию.

A> jni. Другая архитектура и переносимо. Так что действительно лучше вовсе помолчать.


*ROTFL*

A>мда, а мужики то не знают, что нельзя и реализуют здесь. Хотя секция ML пуста.


Учился б ты читать, однако. Мне нужна эффективная реализация, а не тот позорный бред.


GNU>> Про наличие отсутствия хвостовых вызовов в убогонькой JVM так же и напоминать как-то неудобно, это очевидная и всем известная засада.

A>Каким образом должны хвостовые вызовы лежать в jvm? Очень интересно.

Префикс .tail в CLI. И хвостовые вызовы должны работать ГАРАНТИРОВАННО.
Re[6]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 11:56
Оценка:
Здравствуйте, n0name2, Вы писали:

GNU>> В JVM нет хвостовой рекурсии. В .NET есть. В JVM нет структур, явно выделяемых на стеке — в .NET есть. В JVM есть лимит на размер методов — явно следующий из привязки к модели разработки на убогом язычке Java — в .NET такого предела нет.


N>И это ты называешь технологическим приемуществом?


yep

N> Собственно, кроме хвостовой рекурсии ни одного более менее серьезного пункта.


Large methods — kinda showstopper. Think about an EFFICIENT FSM implementation, pal.

N> Хотя, это тоже вполне решаемый вопрос, если бы кому-то она была бы всерьез нужна — давно бы сделали.


Фигнаны. Изначально заложенная ошибка проектирования.

N>Размер методов — стыдно вообще об этом упомянать, обходится элементарно,


Muahahahahaha! Элементарно? Жду примера элементарно реализованного ЭФФЕКТИВНОГО интерпретатора байткодов для относительно сложной VM.

N> Причем, это будет прозрачно для программиста, не нужно будет использовать разные сущности для того, чтобы добится аллокации на стеке.


А оно мне надо? Мне нужна гибкость и контроль.

N>Если так подходить, то, у JVM есть свои технологические приемущества, актуальные для императивных языков — в Java есть примитивные типы данных, более эффективные чем структуры,


?!?
:-O

N> в Java есть escape analysis, в Java есть hotspot машина, в Java есть быстрый biased locking и т.д.


ROTFL
Re[5]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 11:58
Оценка: -10
Здравствуйте, Alexandro, Вы писали:

GNU>> Смешное ты существо. Я под JVM около десятка разнообразных компиляторов написал. Для Java я писал source->source трансляторы и системы статического анализа кода. Я, в отличии от тебя, малограмотного, очень даже хорошо знаю, о чём говорю.


A>Я не опущусь до оскорбления таких ничтожеств как ты. Закончил.


Гы, сына, ЛОЛ! Маленький ламерок обиделся, как это трогательно!
Re[7]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 12:50
Оценка:
Здравствуйте, Андрей Хропов, Вы писали:

АХ>Ну это в общем-то не слишком далеко ушло от

АХ>
АХ>Runtime.getRuntime().exec("javac myprogram.java");
АХ>


А какой функционал нужен то? Не хватает компилятора... Ну, юзай тогда другие средства генерации байт кода. Их полно (библиотек), BCEL, ASM, Javassist. Напиши кусок кода, и я тебе скажу как его проще всего сдалать на Java.

АХ>These interfaces and classes are required as part of the Java™ Platform, Standard Edition (Java SE), but there is no requirement to provide any tools implementing them.

АХ>There is no requirement for a compiler at runtime.
АХ>[/q]

Реально compiler API работает. Лично мне этого достаточно.

АХ>Как это не вынесено? Я вынес. Там замеряется время внутри. Более того, функция также вызывается и до измерения.


Для того, чтобы было более-менее корректно, в общем случае, нужно сначала прогнать в цикле исполнение функции более N раз, где N это CompilerThreshold, она разная по умолчанию для разных типов JVM, можно ее задавать. А лучше — прогнать еще больше раз т.к. hotspot может несколько раз перекомпилировать метод на лету чтобы улучшить производительность.

Т.е. нужно не сначала погонять код, потом начать отсчет замера. Примерно так

void test() {
}

void main() {
for (int i = 0;i < 100 * 1000;i++) test();
long start = System.nanoTime();
for (int i = 0;i < 100 * 1000;i++) test();
long elapsed = System.nanoTime() - start;
}


Плюс -server нужно использовать практически всегда, также есть много полезных опций в т.ч. -XX:+AgressiveOpts -XX:+BiasedLocking и много других. Каждая из которых нужна для своих задач — для ускорения locking, для оптимизаций работы с большой кучей и т.д. и т.п.

Еще посмотри здесь.

N>>Как минимум, нужно вставлять -Xcomp -Xbatch и результаты будут в разы лучше.

АХ>1) Это нестандартные флаги и не во всех VM они есть:

Это неважно. Разные JVM действительно имеют свои особенности, но это не значит что их не надо использовать. Кстати, поставь Java6. И еще Excelsior JET для полноты коллекции.

АХ> -Xms<size> set initial Java heap size

АХ> -Xmx<size> set maximum Java heap size
АХ> -Xss<size> set java thread stack size
АХ> -Xprof output cpu profiling data
АХ> -Xfuture enable strictest checks, anticipating future default
АХ> -Xrs reduce use of OS signals by Java/VM (see documentation)

Это примерно 10% от всех доступных опций. Большинство из них описано в детальной документации. Их очень много. здесь но это не все... Более правильные доки есть для каждой конкретной версии JVM.

АХ>2) попробовал HotSpot с -Xcomp -Xbatch (-Xcomp оказывается работает, правда об этом в опциях ни слова ).

АХ> Небольшое ускорение в обычном цикле (все равно ~ в 8 раз медленее MS.NET):
АХ>

АХ>Simple do-while: 1352
АХ>Repeat until: 4006


У меня на Java6 client примерно 700ms/2000ms. Но, еще раз повторюсь — в данном конкретном случае это баг server JVM и нежелание Scala использовать встроенный boolean.

АХ>В моих тестах замер делается внутри (т.е. время на старт не учитывается), запускал на разных VM и -server и -client (об этом тоже писал), причем не всегда -server лучше. То что HotSpot иногда вылетает в интерпретацию — так это его реальные условия работы: все честно. Про другие грубые ошибки прошу поподробнее.


Нет, просто замера недостаточно, нужно еще отбрасывать то время, которое тратит компилятор на создание native code. См выше. Он это делает ПАРАЛЛЕЛЬНО с исполнением кода в интерпретируемом режиме. HotSpot работает как интерпретатор только для тех участков кода, которые оно считает недостойными компиляции (оч редко вызываемыми) и для которых производителность совершенно неважна. Так что сравнивать скорость интерпретации и скомпилированного кода это бредовая затея.

Основные ключи, которые нужно указывать обязательно для микробенчмарков (Java6, HotSpot): -server -Xmx512m -Xms512m -XX:+AggressiveOpts -XX:+DoEscapeAnalysis -XX:+UseBiasedLocking

-Xcomp -Xbatch нужы только для того, чтобы компиляция прошла сразу а не параллельно с исполнением кода. Но, по хорошему так делать не нужно т.к. вначале у HotSpot нет информации о том, как себя код ведет в runtime. Лучше использовать техники, описанные выше.

Если это тест на создание объектов и/или скорость GC то тут тоже есть тонкости, нужно по максимуму использовать Thread Local Object Allocation, ключи соот-ие сходу не помню. Ну, и опции по использованию throughput parallell GC (если нужен throughput) или concurrent low pause GC (если нужны короткие паузы).

Для JRockit опции совершенно другие, если нужно будет — напишу о них.

N>>Например, примитивные типы данных работают быстрее в Java т.к. это не value типы, а отдельная сущность.

АХ>Это как это они быстрее value типов ? Примеры давай.

Простейшие задачи — работа с массивом double/long. Например, сортировка пузырьком. Есть у .NET C# компилятор, который можно скачать без Visual Studio (command line only)? Если да, то могу попробовать написать такого рода тест.

N>>Или вот в последнем JDK сделали lock elimination/coalesce с помощью escape analysis. Теперь легко можно будет сделать бенчмарк в котором на синхронизации Java будет на порядок быстрее.

АХ>ссылка, пример?

Пример простейший

public class Test30 {
    public int i = 0;
    public synchronized void test() { i++; }

    public static void x(String[] args) {
        long start = System.nanoTime();
        Test30 t = new Test30();
        for (int i = 0; i < 1000 * 1000; i++) t.test();
        System.out.println("Elapsed: " + (double)(System.nanoTime() - start) / 1.0e6);
    }

    public static void main(String[] args) {
        x(args); x(args); x(args); x(args);
    }
}


Без escape analysis, просто -server

Elapsed: 33.746606
Elapsed: 43.532647
Elapsed: 26.349442
Elapsed: 28.652816


C escape analysis (-server -XX:+DoEscapeAnalysis)

Elapsed: 46.199678
Elapsed: 43.042022
Elapsed: 2.238267
Elapsed: 2.646585


Работает с тойже скоростью что и без synchronized если JVM определит что другие потоки не сонхронизуются на томже мониторе. Еще умеет synchronized блоки объеденять.

здесь. К сожалению, литература по этому вопросу в основном относится к разного рода research, про конкретную имплементацию мало пишут.

N>>Из того, что я еще могу вспомнить — в Java гораздо более продвинутая memory model,

АХ>А чем это она так особо продвинутая?

Тем, что не гарантирует видимость переменных, записыных в память одним потоком другому потоку. Для этого обязательно нужно использовать synchronize или volatile переменные. Это позволяет компилятору и вообще runtime делать много оптимизаций. Плюс это позволяет нормально работать на nccNUMA архитектурах (вообще говоря, за ними будующее).

N>> которая позволяет компилятору делать очень много оптимизаций и собственно hotspot в то время как основную компиляцию в bytecode .NET делает один раз.

АХ>HotSpot и сам ресурсы отъедает, так что на практике один хрен, а подчас даже хуже (может улететь в интерпретацию).
АХ>Но в принципе да, подход неплохой.

Конечно, интерпретация гораздо медленнее. Но, в реальной жизне а не в микробенчмарках это незаметно т.к. интерпретируются только редко используемые куски кода. А подход очень правильный т.к. компиляция итеративна и код постоянно улучшается в зависимости от метрик. И HotSpot когда все скомпилировалось есть уже мало ресурсов.

N>>Короче, еще раз, по большей части песни о немеряном технологическом приемуществе .NET VM над JVM это чистый маркетинг.

АХ>Да оно не немеряное, но некоторое есть.

Ну у JVM тоже есть свои.

N>> Корректный микробенчмарк сделать и запустить на JVM не так просто, но, она для этого и не предназначена.

АХ>Во-во. Почему-то под .NET и без танцев с бубнами все несколько быстрее.

Ну так JVM не для микробенчмарков создавалась а для выполнения реальных приложений.
Re[7]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 13:01
Оценка:
Здравствуйте, GNUzaurus, Вы писали:

GNU> Large methods — kinda showstopper. Think about an EFFICIENT FSM implementation, pal.


Если не нужно чтобы метод был виртуальным (нет его переопределений), Java его не будет в native code делать таковым. Тебе в методе стек большой нужен? Его можно заменить переменными класса?

N>> Хотя, это тоже вполне решаемый вопрос, если бы кому-то она была бы всерьез нужна — давно бы сделали.


GNU> Фигнаны. Изначально заложенная ошибка проектирования.


Размеры метода — всего лишь ограничение формата классов. Просто сделать новую спецификацию и все. С tail recursion — там все в security упирыется, но, это не проблема если весь код в одном security domain находится (99.99% случаев). Ниче там фундаментального нет совершенно.

N>> Причем, это будет прозрачно для программиста, не нужно будет использовать разные сущности для того, чтобы добится аллокации на стеке.

GNU> А оно мне надо? Мне нужна гибкость и контроль.

Конечно надо. Один и тотже класс будет создаватся или в хипе или на стеке в зависимости от того, как его использовать. Сильно упрощает все.
Re[8]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 14:16
Оценка:
Здравствуйте, n0name2, Вы писали:

GNU>> Large methods — kinda showstopper. Think about an EFFICIENT FSM implementation, pal.


N>Если не нужно чтобы метод был виртуальным (нет его переопределений), Java его не будет в native code делать таковым. Тебе в методе стек большой нужен? Его можно заменить переменными класса?


Мне нужны переходы внутри метода. Если метод разбить на несколько, то переходы станут вызовами, и тогда начнет расти стек.

GNU>> Фигнаны. Изначально заложенная ошибка проектирования.


N>Размеры метода — всего лишь ограничение формата классов. Просто сделать новую спецификацию и все.


Я пробовал этот вопрос изучить. Облом там выходит — не получится обратной совместимости.

N> С tail recursion — там все в security упирыется, но, это не проблема если весь код в одном security domain находится (99.99% случаев). Ниче там фундаментального нет совершенно.


Естъ. Стековые операции вроде swap, которых в дотнете нет вовсе.

GNU>> А оно мне надо? Мне нужна гибкость и контроль.


N>Конечно надо. Один и тотже класс будет создаватся или в хипе или на стеке в зависимости от того, как его использовать. Сильно упрощает все.


Не упрощает ни фига. Производительность страдает — во время компиляции я лучше знаю, кому в стек, а кому в кучу. Hotspot знает меньше, он глупее.
Re[9]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 14:32
Оценка:
Здравствуйте, GNUzaurus, Вы писали:

GNU> Мне нужны переходы внутри метода. Если метод разбить на несколько, то переходы станут вызовами, и тогда начнет расти стек.


А если FSM разделить на две половины (или неважно сколько частей), и половину переходов делать в одном методе, половину в другом, то стек будет расти не так сильно. Да и выходить можно из фрэйма назад чтобы стек не разростался...

Но, вообще, все-таки в реальных задачах гораздо больше времени тратится на работу в рамках некоторого одного состояния. Так что накладные расходы FSM, по крайней мере для тех задач с которыми я встречался были совершенно неважны.

Хотя, если вся программа это большая FSM, то да, тут косяк.

N>>Размеры метода — всего лишь ограничение формата классов. Просто сделать новую спецификацию и все.

GNU> Я пробовал этот вопрос изучить. Облом там выходит — не получится обратной совместимости.

А она и не нужна. Совместимости по версиям class files сверху вних нет и сейчас, classes от Java5 на Java1.4.x не запустить. Только снизу вверх.

N>> С tail recursion — там все в security упирыется, но, это не проблема если весь код в одном security domain находится (99.99% случаев). Ниче там фундаментального нет совершенно.

GNU> Естъ. Стековые операции вроде swap, которых в дотнете нет вовсе.

Может быть, но, все-таки раз в IBM JVM это сделали, то и в Sun HotSpot запихают при желании.

N>>Конечно надо. Один и тотже класс будет создаватся или в хипе или на стеке в зависимости от того, как его использовать. Сильно упрощает все.

GNU> Не упрощает ни фига. Производительность страдает — во время компиляции я лучше знаю, кому в стек, а кому в кучу. Hotspot знает меньше, он глупее.

Неа, HotSpot знает больше. Вот ты сделал библиотеку, допустим, там есть класс Line { int x0, y0, x1, y1; void draw(); }. И ты не знаешь как его будут юзать в тех приложениях, которые твою библиотеку пользуют. Либо они будут создавать Line и он будеь not escaped (т.е. в рамках фрейма конкретного метода и заинлайненых в него методов), либо его будут таскать туда-сюда.

А HotSpot это знает и в одном случае его на стеке положит, в другом в куче.
Re[10]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 14:51
Оценка:
Здравствуйте, n0name2, Вы писали:

N>А если FSM разделить на две половины (или неважно сколько частей), и половину переходов делать в одном методе, половину в другом, то стек будет расти не так сильно. Да и выходить можно из фрэйма назад чтобы стек не разростался...


Плохая затычка. Общего и универсального решения не получится. И вообще, стек расти не должен — мы ведь не знаем, что за дрянь нам на вход подсунут, ситуация с стацк оверфлощ будет при таком подходе возможной всегда.

N>Но, вообще, все-таки в реальных задачах гораздо больше времени тратится на работу в рамках некоторого одного состояния.


Парсер. Любой. Узкое место — переходы.

N>Так что накладные расходы FSM, по крайней мере для тех задач с которыми я встречался были совершенно неважны.


Мне б такие задачи...

N>Хотя, если вся программа это большая FSM, то да, тут косяк.


Очень частый случай.

N>А она и не нужна. Совместимости по версиям class files сверху вних нет и сейчас, classes от Java5 на Java1.4.x не запустить. Только снизу вверх.


Снизу вверх тоже ломается.

N>Может быть, но, все-таки раз в IBM JVM это сделали, то и в Sun HotSpot запихают при желании.


Сделали — но без гарантии. То есть, пользы от нее — никакой.

GNU>> Не упрощает ни фига. Производительность страдает — во время компиляции я лучше знаю, кому в стек, а кому в кучу. Hotspot знает меньше, он глупее.


N>Неа, HotSpot знает больше.


Не знает. У меня инфа о статических типах была — а у хотспота уже нет ее. Да и времени на оптимизацию у меня гораздо больше.

N> Вот ты сделал библиотеку, допустим, там есть класс Line { int x0, y0, x1, y1; void draw(); }. И ты не знаешь как его будут юзать в тех приложениях, которые твою библиотеку пользуют. Либо они будут создавать Line и он будеь not escaped (т.е. в рамках фрейма конкретного метода и заинлайненых в него методов), либо его будут таскать туда-сюда.


Я сделаю полиморфную библиотеку. И код от нее инлайниться будет, вообще без вызовов обойдемся. Но JVM мне руки выкручивает, я так только в .НЕТ могу.

N>А HotSpot это знает и в одном случае его на стеке положит, в другом в куче.


Но вызовы методов библиотеки всегда будут по ссылке. Дорого.
Re[11]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 16:33
Оценка:
Здравствуйте, GNUzaurus, Вы писали:

N>>Но, вообще, все-таки в реальных задачах гораздо больше времени тратится на работу в рамках некоторого одного состояния.

GNU> Парсер. Любой. Узкое место — переходы.

Незнаю, javac довольно шустро работает. С JavaCC особенно не натыкался на ограничения. Хотя, все может быть, если шибко сложный парсер нужен. Я только с простыми языками вроде тойже Java работал, ну и для HTML там парсер...

N>>Так что накладные расходы FSM, по крайней мере для тех задач с которыми я встречался были совершенно неважны.

GNU> Мне б такие задачи...

Собственно, автоматизация бизнеса, веб приложения и т.д. 90% применений что Java что C# из этой области, ИМХО.

N>>А она и не нужна. Совместимости по версиям class files сверху вних нет и сейчас, classes от Java5 на Java1.4.x не запустить. Только снизу вверх.

GNU>Снизу вверх тоже ломается.

Почему? Что мешает на лету расширять размеры таблиц в классах до 32х битных или транслировать байт код в новую версию?

N>>Может быть, но, все-таки раз в IBM JVM это сделали, то и в Sun HotSpot запихают при желании.

GNU>Сделали — но без гарантии. То есть, пользы от нее — никакой.

Побробнее, если не сложно.

GNU> Не знает. У меня инфа о статических типах была — а у хотспота уже нет ее. Да и времени на оптимизацию у меня гораздо больше.


Времени у HotSpot предостаточно, несколько раз перекомпилирует тело метода, он может часами статистику собирать. И не для всего нужны оптимизации серьезные, собственно, спотов в программе не так уж и много.

А то, что было до type erasure ну... наверное интересно, но, не особенно. Все равно runtime type checks нужны будут в любом случае.

GNU> Я сделаю полиморфную библиотеку. И код от нее инлайниться будет, вообще без вызовов обойдемся. Но JVM мне руки выкручивает, я так только в .НЕТ могу.


А как ты полиморфную библиотеку на value types сделаешь если Unlike reference types, it is not possible to derive a new type from a value type?

GNU> Но вызовы методов библиотеки всегда будут по ссылке. Дорого.


HotSpot определяет если виртуальный метод нам сейчас не нужен, то заинлайнит, невопрос. Это .NET руки выкручивает — юзай кастрированные классы если хочешь чтобы они были в стеке.
Re[12]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 16:49
Оценка:
Здравствуйте, n0name2, Вы писали:

GNU>> Парсер. Любой. Узкое место — переходы.


N>Незнаю, javac довольно шустро работает. С JavaCC особенно не натыкался на ограничения.


Binary parsing — более тяжкий случай. В javac все равно не в парсере bottleneck.

GNU>> Мне б такие задачи...


N>Собственно, автоматизация бизнеса, веб приложения и т.д. 90% применений что Java что C# из этой области, ИМХО.


Расплывчато. Даже в этих категориях порой встречается rocket science.

N>Почему? Что мешает на лету расширять размеры таблиц в классах до 32х битных или транслировать байт код в новую версию?


А вот про трансляцию я пока не думал. Буду думать заново.

GNU>>Сделали — но без гарантии. То есть, пользы от нее — никакой.


N>Побробнее, если не сложно.


Там не каждый хвостовой вызов корректно определяется и не каждый оптимизируется. То есть, рассчитывать на хвостатость рекурсии нельзя — могут и обломать.

GNU>> Не знает. У меня инфа о статических типах была — а у хотспота уже нет ее. Да и времени на оптимизацию у меня гораздо больше.


N>Времени у HotSpot предостаточно, несколько раз перекомпилирует тело метода, он может часами статистику собирать.


Мне не надо часами собирать. Мне надо сразу быстрый отклик поиметь — пусть даже это ни фига не хотспот и в этом коде и процента времени не наберется — мне не только интегральная производительность требуется, но и локальная.

N>А то, что было до type erasure ну... наверное интересно, но, не особенно. Все равно runtime type checks нужны будут в любом случае.


Не, runtime — не нужны. Все было во время компиляции, а после только туплы с тагами остались.

GNU>> Я сделаю полиморфную библиотеку. И код от нее инлайниться будет, вообще без вызовов обойдемся. Но JVM мне руки выкручивает, я так только в .НЕТ могу.


N>А как ты полиморфную библиотеку на value types сделаешь если Unlike reference types, it is not possible to derive a new type from a value type?


А мне вообще система типов в .NET и в JVM по сараю, мне все эти классы-шмассы только мешают. У меня свои системы типов.

GNU>> Но вызовы методов библиотеки всегда будут по ссылке. Дорого.


N>HotSpot определяет если виртуальный метод нам сейчас не нужен, то заинлайнит, невопрос.


Он это делает дюже погано.

N>Это .NET руки выкручивает — юзай кастрированные классы если хочешь чтобы они были в стеке.


Мне классы вообще не нужны, и я рад возможности пользовать более внятные структуры.
Re[13]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 17:24
Оценка:
Здравствуйте, GNUzaurus, Вы писали:

N>>Собственно, автоматизация бизнеса, веб приложения и т.д. 90% применений что Java что C# из этой области, ИМХО.

GNU> Расплывчато. Даже в этих категориях порой встречается rocket science.

Бывает, но, совсем чуть-чуть и в принципе в рамках ограничений JVM вполне решается.

GNU> Там не каждый хвостовой вызов корректно определяется и не каждый оптимизируется. То есть, рассчитывать на хвостатость рекурсии нельзя — могут и обломать.


Собственно, генерить код надо по одинаковому паттерну да и все. Все-таки, хвостовая рекурсия штука несложная.

Кстати, читал что этот explicit tail rec instruction в .NET типа все равно довольно медленный т.к. security domains проверяет каждый раз.

И вообще, раз уж собственный компилятор, почему бы сразу в цикл ее не разворачивать, у меня IDE и то это предлагает сделать автоматически.

GNU> Мне не надо часами собирать. Мне надо сразу быстрый отклик поиметь — пусть даже это ни фига не хотспот и в этом коде и процента времени не наберется — мне не только интегральная производительность требуется, но и локальная.


Невопрос — скомпилируй в native executable с помощью excelsior jet. Там, кстати, stack allocation уже сделали здесь. Классический компилятор, type erasure его особенно не косается. Скорее всего, и tail rec оптимизирована.

GNU> А мне вообще система типов в .NET и в JVM по сараю, мне все эти классы-шмассы только мешают. У меня свои системы типов.

GNU>Мне классы вообще не нужны, и я рад возможности пользовать более внятные структуры.

Смысл тогда вообще .NET/JVM юзать — интероперабельности с библиотеками не добится, а в этом их основная ценность... Разве что ради имплементации GC...
Re[14]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 17:41
Оценка:
Здравствуйте, n0name2, Вы писали:

GNU>> Расплывчато. Даже в этих категориях порой встречается rocket science.


N>Бывает, но, совсем чуть-чуть и в принципе в рамках ограничений JVM вполне решается.


Увы, если работать эффективно, не тратить время на легкоавтоматизируемую рутину (ту, которую в отсталых конторах разгребают руками посредственных "кодеров"), то именно такие задачи и становятся главным тормозом. И плохо, когда ограничения среды, рассчитаной на посредственных программистов, мешают эффективно работать хорошим и грамотным товарищам.

GNU>> Там не каждый хвостовой вызов корректно определяется и не каждый оптимизируется. То есть, рассчитывать на хвостатость рекурсии нельзя — могут и обломать.


N>Собственно, генерить код надо по одинаковому паттерну да и все. Все-таки, хвостовая рекурсия штука несложная.


Я такого стабильно срабатывающего шаблона пока не нашел.


N>Кстати, читал что этот explicit tail rec instruction в .NET типа все равно довольно медленный т.к. security domains проверяет каждый раз.


Конкретно — в 3-4 раза медленнее локального перехода.

N>И вообще, раз уж собственный компилятор, почему бы сразу в цикл ее не разворачивать, у меня IDE и то это предлагает сделать автоматически.


Это далеко не всегда возможно. Особенно если вызываемую аункцую или замыкание мы получаем как аргумент текущей функции.

N>Невопрос — скомпилируй в native executable


Когда есть возможность использовать нейтив, я и компиляю сразу в нейтив, без посредников. Мне тогда даром все эти жабы с дотнетами не нужны. Увы, это не всегда возможно — тот же J2ME, хотя бы.

GNU>>Мне классы вообще не нужны, и я рад возможности пользовать более внятные структуры.


N>Смысл тогда вообще .NET/JVM юзать — интероперабельности с библиотеками не добится,


Добиваюсь. Через дополнительную прослойку.

N> а в этом их основная ценность... Разве что ради имплементации GC...


К сожалению, выбор платформы часто строго ограничен.
Re[15]: C# .NET vs Java 1.5
От: n0name2  
Дата: 27.12.06 18:11
Оценка:
Здравствуйте, GNUzaurus, Вы писали:

N>>Кстати, читал что этот explicit tail rec instruction в .NET типа все равно довольно медленный т.к. security domains проверяет каждый раз.

GNU> Конкретно — в 3-4 раза медленнее локального перехода.

Тогда действительно видимо приходится здоровенную стэйт машину делать... С таким оверхедом, в принципе, можно попробовать и в Java что-то придумать вроде trampalins.

N>>Невопрос — скомпилируй в native executable

GNU> Когда есть возможность использовать нейтив, я и компиляю сразу в нейтив, без посредников. Мне тогда даром все эти жабы с дотнетами не нужны. Увы, это не всегда возможно — тот же J2ME, хотя бы.

Ну так на .NET ведь ты exe файл получаешь на выходе. Тут тоже самое. Для J2ME конечно не катит, без вопросов.
Re[16]: C# .NET vs Java 1.5
От: GNUzaurus  
Дата: 27.12.06 18:58
Оценка:
Здравствуйте, n0name2, Вы писали:

N>Ну так на .NET ведь ты exe файл получаешь на выходе.


Да какой это exe... Там байткоды некомпилированные.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.