- 1
- 2
- 3
- 4
uint64_t search(StringList& who, const string& aName, const string& aSize,TypeModes aTypeMode, SizeModes aSizeMode, const string& aToken, const StringList& aExtList, void* aOwner = NULL)
{
return search(who, aName, Util::toInt64(aSize), aTypeMode, aSizeMode, aToken, aExtList,aOwner);
}
Точнее вам скажут авторы своих слов, если наткнутся на этот пост.
Прям как return this, ей богу
Т.е. нормально 7, максимально 9, больше гении.
5-7
лол, ну это так же тупо, как и сказать, что функция void foo(object* v) перерабатывает 4 байта только потому что на входе даётся один указатель... а то что эта функция в своём теле может перелопачивать терабайты данных -- это как-то пофигу, ага...
то же самое с человеком, это 15 — 16 бит в сек. -- это только размер ссылок на сложные объекты этого мира. внутри там пипец чо творится же. любой компутер позавидует.
http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/ArrayUtil.java
Но там явно имеет место оптимизация размера байткода.
(кажется, этот код уже когда-то проскакивал на ГК)
http://govnokod.ru/4027
лучше логически зависимые параметры объединять в структуры.
Например, void move(int x,int y) - вполне ничего, но можно и void move(Point point).
А иногда параметры никак не соотносятся, кроме как отношением "параметры этой функции". В таком случае вполне можно оставить и десяток параметров, но можно и создать специальную структуру "для этого случая".
Плюсы и минусы двух подходов, думаю, очевидны:
когда много параметров:
- запись громоздкая и рассеивающая внимание при заполнении вызова
+ быстрый и экономный вызов
передача структуры:
+ более понятное API
+ структуру можно использовать повторно
- фрагментация памяти при выделении и уничтожении краткоживущих объектов, возможны утечки памяти
- особенно в циклах заметно падение производительности при многократном создании\уничтожении таких структур
В любом случае, 100500 параметров для функции - верный признак, что у вас беда в проектировании, и чаще всего вам нужно создавать не структуру параметров, а вынести большинство параметров в поля класса или глобальные переменные.
Обычно, лучший выбор для хранения в полях - редкоизменяемые значения, для параметров - значения менее предсказуемые.
согласитесь, пример, переписанный так, глуп:
this.x=0;
this.y=0;
this.move();//внутри используются поля x и y.
-
исчерпывающе?
Ещё + структуры:
Можно задать конструктор по умолчанию и вообще добавить функций для лёгкой инициализации членов структуры за 1-несколько вызовов.
>когда много параметров:
>+ быстрый и экономный вызов
Быстрее передать одну ссылку на структуру в стеке, чем кучу параметров.
Конечно, лучше когда все параметры находятся в классе\структуре, помещенные туда конструктором или конструктором по умолчанию, а ты просто вызываешь одну функцию без лишних параметров.
можно - но обычно нам надо менять все параметры, а тогда проблема рекурсируется.
> одну ссылку на структуру в стеке
плюс создание\уничтожение структуры в куче
Не всегда. Да вы и сами сказали, что иногда можно переиспользовать структуру при повторных вызовах функций. Не знаю как у вас, но у меня часто параметры функции не меняются почти и вынесены в поля класса.
>плюс создание\уничтожение структуры в куче
GCпроблема. К С++ это не относится.
правильно, в одном случае лучше так, в другом - иначе. Как именно - это приходит с опытом )
> GCпроблема
т.е. new и delete срабатывают мгновенно?
>Быстрее передать одну ссылку на структуру в стеке
>В С++ выделение\освобождение памяти под объект в стеке
Если у Java/C# проблемы со стеком из-за боксинга, то это не мои проблемы.
>плюс создание\уничтожение структуры в куче
>GCпроблема. К С++ это не относится.
По-моему, никакого боксинга быть не должно, если передаваемый параметр соответствует типу аргумента.
Это говорил не я. Тем более это минус.
>По-моему, никакого боксинга быть не должно, если передаваемый параметр соответствует типу аргумента.
GC не сможет следить за временем жизни переданного параметра, если он создан на стеке. Поэтому созданная на стеке переменная боксируется и дальше жизнью её копии управляет GC.
По крайней мере так сделано в C#. Можно ли на стеке создать переменную в Java - не знаю.
В C# для этого используется ключевое слово stackalloc. Также на стеке создаются простые типы данных и struct.
нет. По задумке авторов, программерам нечего заморачиваться такими вещами.
т.е. явно указать. Этими вещами заведует JVM по своему усмотрению
В каком случае? Например тут никакого боксинга нет:
Да, GC не следит за стековыми переменными/структурами. Зачем? Они удалятся, когда выйдут из области видимости, как и в любом другом языке.
> В C# для этого используется ключевое слово stackalloc.
stackalloc предназначен для выделения буферов на стеке. Простые переменные и структуры создаются без него.
> Также на стеке создаются простые типы данных и struct.
Тавтология. В шарпушечке простые типы данных и есть struct.
Но если уж на то пошло, они могут создаваться и в куче (когда нужно).
Подытоживая: зачем вы берётесь судить о вещах, в которых не разбираетесь?
Подтверждаю всем своим ником.
http://www.ibm.com/developerworks/java/library/j-jtp01274/index.html
На тот момент это были планы, но в HotSpot 1.6 это уже точно есть и работает. Вообще, JVM сейчас имеет самый зверский JIT. Можете почитать про него в этом блоге:
http://blogs.oracle.com/vmrobot/
P.S. Я не фанбой Жабы, но присматриваюсь к ее бэкэнду, разочаровавшись в LLVM.
А на байт-коде микрооптимизации и описываются естественно, и проход по байт-коду значительно быстрее, да и памяти занимается ощутимо меньше.
Да и байт-код генерировать сложнее, наверное.
А тебе это зачем - тоже хочешь писать программы, умеющие на ходу создавать участки кода (разный код для разных вводимых данных) и выполнять их? Да, языков, в которых есть такая возможность, пока нету, увы... Почему-то обошли эту тему.
Практически любой (нормальный) компилятор сначала создаёт AST, а потом уже из этого дерева получается байт-код или машинный код. До железа AST не доходит.
Java до сих пор полная хуйгя по поводу создания короткоживущих структур. Напр. разработчику физического движка JBullet пришлось делать кучу хаков чтобы оно работало сносно, т.к. расчёт физики требует создания множества векторов и матриц. У него изображение скакало и программа хрипела и пердела, потому что каждую секунду происходила сборка мусора.
Почти у любой java-проги можно использование памяти в два раза урезать, просто введя byvalue-структуры на уровне виртуальной машины.
Вот только этого не надо. :)
а вот если язык процедурен - тоже приходится придумывать подход :)
Даже на Си используют семантическую эмуляцию ооп
Скажем, если есть понятие "модуля" - тогда переменные уровня модуля :)
Просто передаётся ссылка во вложенные вызовы функций или эти самые вложенные вызываемые функции - методы этой структуры. В чем проблема?
В С++ не уверен, что также, а в дельфи в регистрах передаются 3 первых параметра (которые лезут в регистр), считая указатель this/self: eax, edx, ecx. Все остальные передаются через стек, т.е. имеет смысл делать стековую структуру параметров и передавать указатель на нее. В особых случаях прирост становится заметным.
Еще в подобных функциях имеет смысл избегать изменения порядка аргументов, т.к. в этом случае придется достать параметры из стека и положить уже в нужном порядке - в случае ДЛЛ никак не оптимизируешь.
Оценивая с позиции читабельности: 3-5 аргументов будет нормально, больше - ну уже некрасиво.
ведь один хрен в функции имеются локальные переменные, т.е. тут получается шило на мыло: было 3 аргумента в стеке, и 3 переменных в регистрах, а стало 3 аргумента в регистрах, и 3 переменных в стеке (плюс добавим время на их реанжировку по надобности)