Здравствуйте, Mamut, Вы писали:
M> H>Да я более чем внятно все объяснял, даже ссылку на вики давал (поверь, там описано все очень внятно). Я думаю тут есть явное нежелание сторонников дотнета признать тот простой факт, что он не кроссплатформенен
M> дотнет — это три разные сущности, какую из них ты имеешь в виду (и да, то, что МС называет эти три сущности одним именем, делу не помогает)
Здравствуйте, Ночной Смотрящий, Вы писали:
НС> H>У дельфей есть пакеты (bpl), тоже можно загрузку динамическую организовать (и подозреваю, что как и в жабе, можно обеспечить прозрачную загрузку из сети)
НС> А инлайнинг будет работать?
Здравствуйте, Ночной Смотрящий, Вы писали: E__>>Что стырено из джавы, но тем не менее, очень даже работает. НС>Это не может быть стырено из джавы, потому что в джаве вообще нет сущности, соответствующей библиотеке. У них класс заодно и единица деплоймента, и умение инлайнить методы чужих классов жизненно необходимо. E__>> И... Внезапно по нему пройдется джит, увидит, что вызываемый метод у класса есть, и его имя в программе статическая строка(т.е. оно выполняется, и будет всегда выполняться именно так). И он его заинлайнит, убрав рефлексию НС>Пруфлинк можно?
Ну, для начала тестик:
Скрытый текст
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class Main {
public static void main(String[] args) throws Throwable {
// Вставляйте смело свой URL, откуда хотите.
// но результат будет одинаков - какая нахрен разница, откуда получнеы байты класса?
URLClassLoader loader = new URLClassLoader(new URL[]{new URL("http://files.rsdn.ru/21658/")});
// грузим класс
Class<?> coolClassClass = loader.loadClass("CoolClass");
// инстанс
Object coolClassInst = coolClassClass.newInstance();
//получаем метод через рефлексию
Method method = coolClassClass.getDeclaredMethod("foo", long.class, long.class);
// чисто утилитарноеint result = 0;
long time = System.nanoTime();
//первый проход, без JITfor(long i = 0; i < 1000; i ++) {
result += (Long)method.invoke(coolClassInst, i, i++);
}
System.err.println(System.nanoTime() - time);
time = System.nanoTime();
// Ждем джитfor(long i = 0; i < 100000000; i ++) {
result += (Long)method.invoke(coolClassInst, i, i++);
}
// это время ради прикола
System.err.println(System.nanoTime() - time);
time = System.nanoTime();
//второй проход, после JITfor(long i = 0; i < 1000; i ++) {
result += (Long)method.invoke(coolClassInst, i, i++);
}
System.err.println(System.nanoTime() - time);
// чисто для того, чтобы не перемешался вывод
Thread.sleep(500);
// чтобы компилытор вообще все не убрал
System.out.println(result);
}
}
Исходник класса(минимализируем вычисления, делая акцент на вызове):
Скрытый текст
public class CoolClass {
public long foo(long a, long b){
return a + b;
}
}
Результаты(в наносекундах):
11759187 // это тормоза от рефлексии, 1000 вызовов
3098936672 // разугрев, 100000000 вызовов, где-то посередке прошелся компилятор
343025 // опа, на 2 порядка выше скорость! И те же 1000 вызовов, как в первом случае!
838457712 // это просто вывод результата - без него компилер расслабится и ваще все выкинет
Асм код не предоставлю, по крайней мере пока(увы, нет времени, если кто подскажет, как посмотреть результать компиляции джавовского джита — буду рад). Но результаты джита в этом случае говорят сами за себя. Он делает код на два порядка быстрее. И джиту еще есть куда развиваться.
И да, говорящему "рефлексия — тормоз" я всегда рад выдать ссылку на этот пост. Да, тормоз. До первого прохода джита. А если этот тормоз что-то решает, то компилятор по нему пройдется, и ускорит. Сильно ускорит.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Трололоша, Вы писали:
E__>>ибо как раз сейчас занимаюсь переводом сишного проекта в жабу(100 строк с++ превращаются в 10 жабовских) Т>У тебя похоже весь С++ код сплошь и рядом самописный, за исключением вызовов стандартных либ.
Не, там адский винегрет многолетней давности. Где-то хорошо, где-то плачешь кровавыми слезами. Переписываю на джаве, пишу обвязки с использованием рефлексии и аннотаций, зачастую не самых понятных(бля, ну как можно понять поля, называющиеся в оригинале и в базе как void1, void2 и так далее?) — но приходится(местами из говнокода, но это чисто утилитарный код для поддержки легаси — мне нельзя что-то сломать, притом никто не знает, как оно должно работать, хотя работает, а хочется сильно сократить эти тонны кода — ну куда эти классы по 10000 строк?), делаю пусть и чутка медленнее(магические цифры — в enum, кучу параметров сущности — в объект, кучу похожих методов — в один, добавляя параметр, которым эти похожие отличаются, ну там много интересного, код сокращается, я хотя-бы все методы в один экран вмещаю, хотя в оригинале там адовые простыни экранов на 5).
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
M>> H>Да я более чем внятно все объяснял, даже ссылку на вики давал (поверь, там описано все очень внятно). Я думаю тут есть явное нежелание сторонников дотнета признать тот простой факт, что он не кроссплатформенен
M>> дотнет — это три разные сущности, какую из них ты имеешь в виду (и да, то, что МС называет эти три сущности одним именем, делу не помогает)
H>Я не говорю о частностях, я о целом.
Не получится. Потому что из этого целого некроссплатформенна только часть.
Здравствуйте, hattab, Вы писали:
H>Рефлексия это не прерогатива менеджед платформ У нынешних дельфей (и видимо C++ Builder'а) RTTI такой, что мама не горюй.
Вот не в курсе. Я там ниже примерчик написал. Напиши, пожалуйста, свой аналог, только как и я — выложи, загружаемый модуль на файлы рсдн, ссылку на основной запускаемый модуль для винды и линуха(который загружаемый модуль берет прямо с рсдн, и сразу юзает), и код. Ну и тайм-мерки тоже не забудь. Мы тут холиварим, но нужно и объективные данные иметь.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, hattab, Вы писали:
H>Ладно, не нравится тебе COM... У дельфей есть пакеты (bpl), тоже можно загрузку динамическую организовать (и подозреваю, что как и в жабе, можно обеспечить прозрачную загрузку из сети)
Пример в студию! Аналог моего кода в джаве — он прост как столб, а копаться в мегабайтах мы не станем.
ЗЫ это не сарказм. Я не знаю нихрена про делфи, отчего бы и не узнать. На примере кода, конечно.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Ночной Смотрящий, Вы писали:
E__>>Ну, как минимум с нативными вещами нужно работать через интероп.
НС>Не обязательно. Это только у джавы такое ограничение. Интероп нужен для относительно безопасной работы с нейтивом.
Согласен, ни разу не приходилось. Но это не значит, что никому это не нужно.
E__>> или получить байты с usb не выйдет.
НС>Получить байты с USB — выйдет.
Просто для знаний(я пока далеко от дотнета ушел) — как?
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Ночной Смотрящий, Вы писали:
H>>У дельфей есть пакеты (bpl), тоже можно загрузку динамическую организовать (и подозреваю, что как и в жабе, можно обеспечить прозрачную загрузку из сети)
НС>А инлайнинг будет работать?
Он только подозревает загрузку из сети, а ты его инлайнами
Как ты себе предсталяешь инлайн в рантайме без виртуальной машины?
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, мыщъх, Вы писали:
М>создание 400х чек-боксов показывает, что программисты совсем разучились думать и хотят готовых _стандартных_ компонентов под нестандартную задачу, хотя она на чем угодно реализуется элементарно и без тормозов и без ограничения на кол-во элементов в гриде. хоть миллион на миллион. ловим событие "щелчок", смотрим где мыша, вычисляем позицию верхнего левого угла элемента, из битового массива берем его состояние, меняем на противоположное и рисуем либо галку либо пустое место.
Здравствуйте, Eugeny__, Вы писали:
E__>Я вам хуже скажу. В джаве можно получить вообще неизвестный класс черти откуда(тупым потоком байт из сети загрузить кастомным класслоадером как Object, но можно придумать и более изощренный сценарий), создать экземпляр(или же вызывать статику — неважно), проверить его на наличие нужного нам метода, и часто вызывать его через рефлексию, даже не кастуя ни к какому известному интерфейсу. И... Внезапно по нему пройдется джит, увидит, что вызываемый метод у класса есть, и его имя в программе статическая строка(т.е. оно выполняется, и будет всегда выполняться именно так). И он его заинлайнит, убрав рефлексию, плюс скомпилит в нативу. Очень прошу примера, как такое возможно в нативе. Это немного похоже на ком(тоже слепой вызов), вот только ком объект не инлайнится никогда. Ваш выход, господа.
Нет, JIT такую магию не умеет.
Там всё проще, java.lang.reflect.Method#invoke(obj, args) делегирует вызов через интерфейс MethodAccessor. Насколько я помню, первые сколько-то вызовов испоьзуется стандартная реализация интерфейса, которая делает вызов используя внутренние методы JVM. После какого-то количества вызовов, генерируется специальная реализация MethodAccessor.invoke(obj, args) { return (TargetObject) obj.targetMethod((Type0) arg0, ...) }, которая впоследствии и используется. Т.е рефлексивный вызов становится обычным вызовом через интерфейс + пара кастов. Вот после этого-то как раз и вступает в работу JIT, и уже тогда он может что-то куда-то заинлайнить.
Попробуй сделать целевой метод приватным, по идее тогда эта оптимизация не должна сработать и вызов будет всегда идти через внутренние методы JVM.
Здравствуйте, Иван Дубров, Вы писали:
ИД>Попробуй сделать целевой метод приватным, по идее тогда эта оптимизация не должна сработать и вызов будет всегда идти через внутренние методы JVM.
P.S. Ммм, походу, всё равно быстро получается Видимо, всё-таки основной прирост от ускорения внутренней механика sun.reflect/java.lang.reflect.
Здравствуйте, NikeByNike, Вы писали:
NBN>>> Отсутствие кроссплатформенности. H>>Виртуальная машина, как раз таки, вполне себе переносима NBN>С++ в теории тоже хорош.
С++ в теории как раз плох, а вот на практике — хорош.
Здравствуйте, Eugeny__, Вы писали:
E__>Не, там адский винегрет многолетней давности. Где-то хорошо, где-то плачешь кровавыми слезами. Переписываю на джаве, пишу обвязки с использованием рефлексии и аннотаций, зачастую не самых понятных(бля, ну как можно понять поля, называющиеся в оригинале и в базе как void1, void2 и так далее?)
Здравствуйте, Eugeny__, Вы писали: E> H>Рефлексия это не прерогатива менеджед платформ У нынешних дельфей (и видимо C++ Builder'а) RTTI такой, что мама не горюй. E> Вот не в курсе. Я там ниже примерчик написал. Напиши, пожалуйста, свой аналог, только как и я — выложи, загружаемый модуль на файлы рсдн, ссылку на основной запускаемый модуль для винды и линуха(который загружаемый модуль берет прямо с рсдн, и сразу юзает), и код. Ну и тайм-мерки тоже не забудь. Мы тут холиварим, но нужно и объективные данные иметь.
С загрузкой делать лень (если честно, лень выносить юнит в пакет , сама загрузка ровно одна строчка ). Но работу с RTTI покажу (Delphi XE2):
Основной код
Program rtti_method_call;
{$APPTYPE CONSOLE}Uses
System.RTTI, System.Diagnostics, CoolUnit;
Var
inst : TObject;
mtd : TRttiMethod;
sw : TStopwatch;
Index : Integer;
Result : Integer;
Proc : Function(Self : Pointer; A, B : Integer) : Integer;
Begin
With TRttiContext.Create.FindType('CoolUnit.TCoolClass').AsInstance Do
Begin
inst := GetMethod('Create').Invoke(MetaclassType, []).AsObject;
mtd := GetMethod('Foo');
End;
sw := TStopwatch.StartNew;
// Вызов средствами RTTIFor Index := 1 To 1000000 Do
Result := Result + mtd.Invoke(Inst, [Index, Index + 1]).AsInteger;
WriteLn(sw.ElapsedMilliseconds); // 4358 msec
// Но мы же знаем сигнатуру метода! И мы в нативе :cool: :) Читерим!!!!!!!
Proc := mtd.CodeAddress;
sw := TStopwatch.StartNew;
// Метод полученный средствами RTTI вызывается напрямую, без малейших проблемFor Index := 1 To 1000000 Do
Result := Result + Proc(inst, Index, Index + 1);
WriteLn(sw.ElapsedMilliseconds); // 1 msecEnd.
Код юнита
Unit CoolUnit;
Interface
Type
TCoolClass = Class(TObject)
Function Foo(A, B : Integer) : Integer;
End;
Implementation
Function TCoolClass.Foo(A, B : Integer) : Integer;
Begin
Result := A + B;
End;
Initialization// Чтоб линкер не выкинул классIf TCoolClass.ClassInfo = NIL Then
Halt;
End.
Исполняемый модуль выкладывать?
Кстати, твой тест я запустить не смог:
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)
Exception in thread "main" java.lang.NoClassDefFoundError: Main/class
Caused by: java.lang.ClassNotFoundException: Main.class
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: Main.class. Program will exit.
Здравствуйте, Eugeny__, Вы писали:
НС>>Не обязательно. Это только у джавы такое ограничение. Интероп нужен для относительно безопасной работы с нейтивом.
E__>+/-
Можно значки расшифровать?
НС>>Зачем? E__>Согласен, ни разу не приходилось. Но это не значит, что никому это не нужно.
Нет, ну есть кое какие ситуации. Но что то мне подсказывает, что автор утверждения совсем не их имел в виду.
НС>>Получить байты с USB — выйдет.
E__>Просто для знаний(я пока далеко от дотнета ушел) — как?
Точно так же, как на С++. CLR это не JVM, unsafe код там никто не отменял.