2010-01-12 3 views
3

Я новичок в java-мире от C++-фона. Я хотел бы перенести некоторый код на C++ на Java. Код использует разреженных векторов:Управление Java и памятью

struct Feature{ 
int index; 
double value; 
}; 

typedef std::vector<Feature> featvec_t; 

Как я понял, если один делает объект, будет некоторые накладные расходы на использование памяти. Таким образом, наивная реализация функции будет значительным, если в наборе featvec_t будет 10-100 миллионов функций.

Как эффективно представлять эту структуру памяти на Java?

ответ

6

Если память действительно является вашим узким местом, попробуйте сохранить данные в двух отдельных массивах: int[] index и double[] value.

Но в большинстве случаев с такой большой структурой производительность (время) будет основной проблемой. В зависимости от операций, выполняемых в основном по вашим данным (вставка, удаление, получение и т. Д.), Вам необходимо выбрать соответствующую структуру данных для хранения объектов класса Feature. Начните свои исследования с интерфейса java.util.Collection, его субинтерфейсов (List, Set и т. Д.) И их реализации, предоставляемые в пакете java.util.

+0

+1 - не пытайтесь решить проблему использования памяти, если вы не уверены, что это настоящая проблема. –

0

Объект в Java (я думаю) есть:

  • SizeOf (индекс)
  • SizeOf (значение)
  • SizeOf (класс *) < - указатель на конкретный класс

Таким образом, разница в четырех байтах от указателя. Если ваша структура равна 4 + 8 = 12 байт, это накладные расходы на 33% ... но я не могу думать о другом (лучшем) способе сделать это.

+0

Вы могли бы избежать создания различных объектов для каждой точки, создав два вектора: один для целых индексов и один для двойных значений, но если это список , он будет иметь значения autobox int в Integer, что будет стоить времени и пространства. Итак ... нет хорошего решения. – helios

+2

Размер указателя может варьироваться в зависимости от JVM. Это не всегда 4 байта. –

+1

О, пожалуйста, пересмотрите, как растет ваш вектор ... если вы знаете размер перед рукой, вы можете создать int [] и double [] для точек и класс, имеющий логику для доступа к элементам. Если вы не знаете размер, но вы его инициализируете в первый раз, вы можете создать два LinkedList (или что угодно, что полезно для добавления большого количества предметов) и преобразовать их в более статическую форму. – helios

5

Чтобы избежать накладных расходов памяти для каждой записи, вы можете написать реализацию java.util.List<Feature>, которая обертывает массивы int и double и строит объекты Feature по требованию.

Чтобы изменить размер изображения, вы можете использовать TIntArrayList и TDoubleArrayList от GNU trove.

+0

Массив все еще не разрежен; Чтобы это получить; Я думаю, что самым простым решением является сохранение значений в TreeMap. – KarlP

+0

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

+0

Разве вы не хотите использовать HashMap для этого вместо TreeMap? – MSalters

1

Возникает вопрос о пространстве для самой структуры или разреженного вектора? Поскольку другие ответили на первое, я застрелю за последнее ...

В стандартных сборниках Java нет никаких редких списков/матриц.

Вы можете создать эквивалент, используя TreeMap, привязанный к индексу.

Смежные вопросы