Keep a global variable or recreate a local variable in c?

I've been programming with Java for Android quite some while now. Since performance is very important for the stuff I am working on I end up just spamming global variables. I guess everyone will come rushing in now and tell me this is the worst style ever, but lets keep it simple. For Android, local variables means garbage collection and garbage collection is something that kills performance.

Lately I have started using the NDK. Now I feel the urge to actually take all the local variables and change them to global variables. I am wondering though if this makes any sense in c code. Obviously it is no good style, but if it is needed for speed I'll sacrifice the style gladly.

I've looked through older threads about local vs global, but I haven't been able to find anything about speed. So my question is, if I am calling a function very often is it relevant for the speed that local variables are created and die after the function is done? Or doesn't it matter at all and I can happily keep on using the local variables.

I would test it myself, but for some reason the performance of my app goes up and down like a roller coaster and I doubt I'll be able to really make any sense of the data. I hope someone can help me out before I rewrite my whole code for nothing :)

6
задан Pandoro 24 August 2010 в 22:14
поделиться

4 ответа

В C разница в производительности зависит от аппаратного обеспечения. Загрузка глобального на RISC-процессор требует больше инструкций (поскольку вам нужно загружать обе половины адреса в отдельных инструкциях, а не добавлять в указатель стека), а затем вам нужно бороться с проблемами кеша. По большей части вы можете рассчитывать на то, что ваши локальные переменные находятся в кеше. Использование глобальных переменных немного перегрузит кеш, и некоторые функции могут быть очень неблагоприятно затронуты.

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

«Стоимость» создания локальной переменной в C равна нулю; это просто удар по регистру (указатель стека), чтобы освободить место для локального. Затем вы инициализируете эту переменную любым подходящим способом. Вы должны быть в состоянии узнать, дорого это или нет, путем случайного осмотра. Когда функция завершается, указатель стека возвращается к своему предыдущему значению, независимо от того, сколько у вас локальных переменных.

Однако, если ваше определение «локальных переменных» — это объекты, размещенные в куче, вы будете страдать от затрат на выделение памяти. Распределение памяти, на мой взгляд, происходит очень медленно, поэтому, что бы вы ни делали, чтобы уйти от malloc/free (и «нового» в Java), тем лучше для вас будет. (Я делаю игры, и мы склонны использовать dlmalloc, но даже это слишком медленно для обычного использования; 400 нс на вызов — это быстро.)

9
ответ дан 8 December 2019 в 05:52
поделиться

Для Android локальные переменные означают сборку мусора ...

Это неверный оператор. Локальные переменные размещаются в стеке, а не динамически выделяются в куче. Ознакомьтесь с этой статьей о том, что где и где выделяется в Java

Как правило, элементы, размещенные в стеке, не требуют сборки мусора / освобождение и "умереть" сразу после того, как выполнение покидает текущую область видимости. Выделение / освобождение стека происходит значительно быстрее, чем выделение в куче и сборка мусора.

Старайтесь избегать глобальных переменных как по стилю, так и по соображениям производительности. Локальные переменные, размещенные в стеке, будут работать намного быстрее.

11
ответ дан 8 December 2019 в 05:52
поделиться

На процессорах на базе MIPS и ARM, которые есть в большинстве телефонов Android, нет никакой причины перемещать локальные переменные в глобальное пространство «для повышения производительности». Локальные переменные хранятся в стеке, и выделение стека выполняется за одну операцию; более того, весь стек очищается сразу при вызове ret . Перемещение их в глобальное пространство просто превратит вашу логику в беспорядочную неразбериху в неразборчивом состоянии без каких-либо преимуществ.

Единственное, о чем следует беспокоиться о perf при создании объектов, - это когда вы размещаете их в куче (например, с помощью malloc () ). Именно здесь C "более производительный", чем языки со сборкой мусора, потому что вы можете видеть и контролировать, когда именно возникают эти ошибки и когда они освобождаются. На самом деле это не тот случай, когда C malloc () быстрее, чем Java new ; скорее, поскольку каждое распределение прозрачно и ясно для вас, вы можете проделать необходимую работу, чтобы гарантировать, что такие медленные операции выполняются как можно реже.

2
ответ дан 8 December 2019 в 05:52
поделиться

Кстати, объявление переменной static внутри функции C даст вам поведение глобальной переменной, не засоряя глобальное пространство имен.

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

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

0
ответ дан 8 December 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: