Какой из следующих типов данных требует наибольшего объема памяти для своего значения

Обновлено: 05.07.2024

Во Free Pascal определен ряд целых типов, различающихся между собой объемом отводимой под данные памяти. Чем больше памяти отводится, тем больший диапазон значений может принимать переменная данного типа.

На практике часто используется целочисленный тип integer, под который в зависимости от платформы отводится 2 или 4 байта.

Примеры часто используемых целых типов в Pascal

Тип Диапазон допустимых значений Отводимая память, в байтах
shortint -128…127 1
integer -32 768…32 767 2
longint -2 147 483 648…2 147 483 647 4
byte 0…255 1
word 0…65 535 2

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

Целочисленные переменные в программе описываются следующим образом:

Здесь a , b , c - имена переменных, integer – тип переменных.

Операции над целыми типами, дающие в результате значение целого типа:

Пример. Пусть a = 17, b = 5. Тогда a div b дает 3, a mod b дает 2 (остаток от деления).

Операции над операндами целого типа выполняются правильно только при условии, что результат и каждый операнд не меньше минимального (крайнего левого) и не больше максимального (крайнего правого) значений диапазона. Например, в Паскале существует константа maxint, в которой содержится максимально допустимое значение для типа integer. Тогда при выполнении операций в программе должны соблюдаться следующие условия:

( a операция b ) <= maxint,
a <= maxint, b <= maxint.

Над целыми типами, как и многими другими, допустимы операции отношения (сравнения). Результат таких операций относится к типу boolean и может принимать одно из двух значений – либо true (истина), либо false (ложь).

Операции отношения

Знак операции Операция
= Равно
<> Не равно
>= Больше или равно
> Больше
<= Меньше или равно
< Меньше

Целые типы могут приниматься в качестве фактических параметров рядом стандартных функций языка программирования Pascal.

Стандартные функции Pascal, применимые к аргументам целых типов

Функция Тип результата Результат выполнения
abs(x) Целый Модуль x (абсолютная величина x)
sqr(x) Целый Квадрат x
succ(x) Целый Следующее значение x (x+1)
pred(x) Целый Предыдущее значение x (x-1)
random(x) Целый Случайное целое число из интервала 0..x-1.
sin(x) Действительный Синус x (угол в радианах)
cos(x) Действительный Косинус x (угол в радианах)
arctan(x) Действительный Арктангенс x (угол в радианах)
ln(x) Действительный Натуральный логарифм x
exp(x) Действительный Экспонента x
sqrt(x) Действительный Квадратный корень из x
odd(x) Логический Значение true, если x – нечетное число; false – если четное.

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

Процедуры inc и dec изменяют значение переданной в них переменной, они ничего не возвращают в программу. Это их важное отличие от функций succ и pred.

Следующие функции принимают в качестве аргументов значения вещественного типа, а возвращают значения целого типа:

trunc(x) – отбрасывание десятичных знаков после точки;
round(x) – округление до целого.

Как я понимаю, обычно тип integer весит 4 байта, в том числе и unsigned integer . Но есть случаи где в зависимости от разрядности процессора integer может иметь как 2 байта так и 8. Не понимаю, как разрядность влияет на размер целочисленного типа и что это меняет для разработчика кроме того, что в него можно вместить шире диапазон чисел(или меньший)?

UPD

Что значить переводить программу из x32 в x64 ? Грубо говоря, это использования типов x64 ? Если я правильно понимаю, причина по которой программа написанная под x64 не будет работать на x32 , это оверхед по память в типах данных? Почему тогда мы можем допустим в Visual Studio выбрать под какую разрядность делать build ? Как это будет влиять на размер самой программы и размер, который будут забирать обычные типы данных?


74.3k 8 8 золотых знаков 67 67 серебряных знаков 124 124 бронзовых знака


2,824 14 14 серебряных знаков 37 37 бронзовых знаков

Есть такая таблица соответствия размеров фундаментальных типов в зависимости от используемой модели данных:

размеры типов

Модель данных в общем случае не привязана непосредственно к железу (разрядности процессора), и зависит от используемой операционной системы (если она присутствует). При этом должно быть очевидно, что на 32bit процессоре не удастся запустить 64bit ОС, но обратное вполне себе имеет место быть.

Размер фундаментальных типов в конкретной реализации компилятора (т.е. под конкретную платформу) подбирается так, чтобы обеспечивать оптимальную производительность.

Помимо увеличения диапазона значений фундаментальных типов, бОльшая разрядность позволяет адресовать больше памяти. Например, при 32bit можно адресовать не более 4Gb, а при 64bit уже 16Eb.

Когда говорят о переводе программы с x32 на x64 имеют в виду, что должна обеспечиваться в первую очередь работоспособность программы в 64bit окружении. Т.е. что из-за изменения размеров типов ничего не сломается. Такого рода проблемы часто возникают, когда при первичной разработке закладываются на фиксированный размер фундаментальных типов, например, что указатель всегда будет 4 байта. А когда при сборке в 64bit режиме он "вдруг" становится в 2 раза больше программа просто начинает крашиться.

Поэтому, чтобы программа была переносима между x32 ↔ x64 при необходимости обеспечить нужную разрядность вычислений стоит полагаться на типы из <cstdint> .

Integer vs int

Все мы знаем, что в java — everything is an object. Кроме, пожалуй, примитивов и ссылок на сами объекты. Давайте рассмотрим две типичных ситуации:

В этих простых строках разница просто огромна, как для JVM так и для ООП. В первом случае, все что у нас есть — это 4-х байтная переменная, которая содержит значение из стека. Во втором случае у нас есть ссылочная переменная и сам объект, на который эта переменная ссылается. Следовательно, если в первом случае мы определено знаем, что занимаемый размер равен:

Забегая вперед скажу — во втором случае количество потребляемой памяти приблизительно в 5 раз больше и зависит от JVM. А теперь давайте разберемся, почему разница настолько огромна.

Из чего же состоит объект?
  • Заголовок объекта;
  • Память для примитивных типов;
  • Память для ссылочных типов;
  • Смещение/выравнивание — по сути, это несколько неиспользуемых байт, что размещаются после данных самого объекта. Это сделано для того, чтобы адрес в памяти всегда был кратным машинному слову, для ускорения чтения из памяти + уменьшения количества бит для указателя на объект + предположительно для уменьшения фрагментации памяти. Стоит также отметить, что в java размер любого объекта кратен 8 байтам!
Структура заголовка объекта
  • Маркировочное слово (mark word) — к сожалению мне так и не удалось найти назначение этой информации, подозреваю что это просто зарезервированная на будущее часть заголовка.
  • Hash Code — каждый объект имеет хеш код. По умолчанию результат вызова метода Object.hashCode() вернет адрес объекта в памяти, тем не менее некоторые сборщики мусора могут перемещать объекты в памяти, но хеш код всегда остается одним и тем же, так как место в заголовке объекта как раз может быть использовано для хранения оригинального значения хеш кода.
  • Garbage Collection Information — каждый java объект содержит информацию нужную для системы управления памятью. Зачастую это один или два бита-флага, но также это может быть, например, некая комбинация битов для хранения количества ссылок на объект.
  • Type Information Block Pointer — содержит информацию о типе объекта. Этот блок включает информацию о таблице виртуальных методов, указатель на объект, который представляет тип и указатели на некоторые дополнительные структуры, для более эффективных вызовов интерфейсов и динамической проверки типов.
  • Lock — каждый объект содержит информацию о состоянии блокировки. Это может быть указатель на объект блокировки или прямое представление блокировки.
  • Array Length — если объект — массив, то заголовок расширяется 4 байтами для хранения длины массива.
Спецификация Java

Известно, что примитивные типы в Java имеют предопределенный размер, этого требует спецификация для переносимости кода. Поэтому не будем останавливаться на примитивах, так как все прекрасно описано по ссылке выше. А что же говорит спецификация для объектов? Ничего, кроме того, что у каждого объекта есть заголовок. Иными словами, размеры экземпляров Ваших классов могут отличатся от одной JVM к другой. Собственно, для простоты изложения я буду приводить примеры на 32-х разрядной Oracle HotSpot JVM. А теперь давайте разберем самые используемые классы Integer и String.

Integer и String

Итак, давайте попробуем подсчитать сколько же будет занимать объект класса Integer в нашей 32-х разрядной HotSpot JVM. Для этого нужно будет заглянуть в сам класс, нам интересны все поля, которые не объявлены как static. Из таких видим только одно — int value. Теперь исходя из информации выше получаем:

Теперь заглянем в класс строки:

И подсчитаем размер:

Ну и это еще не все… Так как строка содержит ссылку на массив символов, то, по сути, мы имеем дело с двумя разными объектами — объектом класса String и самим массивом, который хранит строку. Это, как бы, верно с точки зрения ООП, но если посмотреть на это со стороны памяти, то к полученному размеру нужно добавить и размер выделенного для символов массива. А это еще 12 байт на сам объект массива + 2 байта на каждый символ строки. Ну и, конечно же, не забываем добавлять выравнивание для кратности 8 байтам. Итого в конечном итоге простая, казалось бы, строка new String(«a») выливается в:

Важно отметить, что new String(«a») и new String(«aa») будут занимать одинаковое количество памяти. Это важно понимать. Типичный пример использования этого факта в свою пользу — поле hash в классе String. Если бы его не было, то объект строки так или иначе занимал бы 24 байта, за счет выравнивания. А так получается что для этих 4-х байтов нашлось очень достойное применение. Гениальное решение, не правда ли?

Размер ссылки

Немножко хотел бы оговорится о ссылочных переменных. В принципе, размер ссылки в JVM зависит от ее разрядности, подозреваю, что для оптимизации. Поэтому в 32-х разрядных JVM размер ссылки обычно 4 байта, а в 64-х разрядных — 8 байт. Хотя это условие и не обязательно.

Группировка полей
Зачем все это?

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

Большие данные – это широкий термин для обозначения нетрадиционных стратегий и технологий, необходимых для сбора, упорядочивания и обработки информации из больших наборов данных. Хотя проблема работы с данными, превышающими вычислительную мощность или возможности хранения одного компьютера, не является новой, в последние годы масштабы и ценность этого типа вычислений значительно расширились.

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

Что такое большие данные?

Точное определение «больших данных» трудно сформулировать, потому что проекты, вендоры, специалисты-практики и бизнес-специалисты используют его совершенно по-разному. Имея это в виду, большие данные можно определить как:

  • Большие наборы данных.
  • Категорию вычислительных стратегий и технологий, которые используются для обработки больших наборов данных.

В этом контексте «большой набор данных» означает набор данных, который слишком велик, чтобы обрабатываться или храниться с помощью традиционных инструментов или на одном компьютере. Это означает, что общий масштаб больших наборов данных постоянно меняется и может значительно варьироваться от случая к случаю.

Системы больших данных

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

В 2001 году Даг Лэйни (Doug Laney) из Gartner представил «три V больших данных», чтобы описать некоторые характеристики, которые отличают обработку больших данных от процесса обработки данных других типов:

  1. Volume (объем данных).
  2. Velocity (скорость накопления и обработки данных).
  3. Variety (разнообразие типов обрабатываемых данных).

Объем данных

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

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

Скорость накопления и обработки

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

Разнообразие типов обрабатываемых данных

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

Данные могут поступать из внутренних систем, таких как логи приложений и серверов, из каналов социальных сетей и других внешних API-интерфейсов, с датчиков физических устройств и из других источников. Целью систем больших данных является обработка потенциально полезных данных независимо от происхождения путем объединения всей информации в единую систему.

Форматы и типы носителей также могут значительно различаться. Медиафайлы (изображения, видео и аудио) объединяются с текстовыми файлами, структурированными логами и т. д. Более традиционные системы обработки данных рассчитывают, что данные попадают в конвейер уже помеченными, отформатированными и организованными, но системы больших данных обычно принимают и сохраняют данные, стараясь сохранить их исходное состояние. В идеале любые преобразования или изменения необработанных данных будут происходить в памяти во время обработки.

Другие характеристики

Со временем специалисты и организации предложили расширить первоначальные «три V», хотя эти нововведения, как правило, описывают проблемы, а не характеристики больших данных.

  • Veracity (достоверность данных): разнообразие источников и сложность обработки могут привести к проблемам при оценке качества данных (и, следовательно, качества полученного анализа).
  • Variability (изменчивость данных): изменение данных приводит к широким изменениям качества. Для идентификации, обработки или фильтрации данных низкого качества могут потребоваться дополнительные ресурсы, которые смогут повысить качество данных.
  • Value (ценность данных): конечная задача больших данных – это ценность. Иногда системы и процессы очень сложны, что затрудняет использование данных и извлечение фактических значений.

Жизненный цикл больших данных

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

Основные категории, связанные с обработкой больших данных:

  • Внесение данных в систему
  • Сохранение данных в хранилище
  • Вычисление и анализ данных
  • Визуализация результатов

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

Кластерные вычисления

Из-за качества больших данных отдельные компьютеры не подходят для обработки данных. Для этого больше подходят кластеры, так как они могут справляться с хранением и вычислительными потребностями больших данных.

Программное обеспечение для кластеризации больших данных объединяет ресурсы многих небольших машин, стремясь обеспечить ряд преимуществ:

  • Объединение ресурсов: для обработки больших наборов данных требуется большое количество ресурсов процессора и памяти, а также много доступного пространства для хранения данных.
  • Высокая доступность: кластеры могут обеспечивать различные уровни отказоустойчивости и доступности, благодаря чему аппаратные или программные сбои не повлияют на доступ к данным и их обработку. Это особенно важно для аналитики в реальном времени.
  • Масштабируемость: кластеры поддерживают быстрое горизонтальное масштабирование (добавление новых машин в кластер).

Для работы в кластере необходимы средства для управления членством в кластере, координации распределения ресурсов и планирования работы с отдельными нодами. Членство в кластерах и распределение ресурсов можно обрабатывать с помощью программ типа Hadoop YARN (Yet Another Resource Negotiator) или Apache Mesos.

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

Получение данных

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

Во время приема данных обычно проводится анализ, сортировка и маркировка. Этот процесс иногда называют ETL (extract, transform, load), что означает извлечение, преобразование и загрузку. Хотя этот термин обычно относится к устаревшим процессам хранения данных, иногда он применяется и к системам больших данных. среди типичных операций – изменение входящих данных для форматирования, категоризация и маркировка, фильтрация или проверка данных на соответствие требованиям.

В идеале, поступившие данные проходят минимальное форматирование.

Хранение данных

После приема данные переходят к компонентам, которые управляют хранилищем.

Обычно для хранения необработанных данных используются распределенные файловые системы. Такие решения, как HDFS от Apache Hadoop, позволяют записывать большие объемы данных на несколько нод в кластере. Эта система обеспечивает вычислительным ресурсам доступ к данным, может загрузить данные в ОЗУ кластера для операций с памятью и обрабатывать сбои компонентов. Вместо HDFS могут использоваться другие распределенные файловые системы, включая Ceph и GlusterFS.

Данные также можно импортировать в другие распределенные системы для более структурированного доступа. Распределенные базы данных, особенно базы данных NoSQL, хорошо подходят для этой роли, поскольку они могут обрабатывать неоднородные данные. Существует множество различных типов распределенных баз данных, выбор зависит от того, как вы хотите организовывать и представлять данные.

Вычисление и анализ данных

Как только данные будут доступны, система может начать обработку. Вычислительный уровень, пожалуй, является самой свободной частью системы, так как требования и подходы здесь могут значительно отличаться в зависимости от типа информации. Данные часто обрабатываются повторно: с помощью одного инструмента, либо с помощью ряда инструментов для обработки различных типов данных.

Пакетная обработка – это один из методов вычисления в больших наборах данных. Этот процесс включает разбивку данных на более мелкие части, планирование обработки каждой части на отдельной машине, перестановку данных на основе промежуточных результатов, а затем вычисление и сбор окончательного результата. Эту стратегию использует MapReduce от Apache Hadoop. Пакетная обработка наиболее полезна при работе с очень большими наборами данных, для которых требуется довольно много вычислений.

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

Apache Storm, Apache Flink и Apache Spark предлагают различные способы реализации обработки в реальном времени. Эти гибкие технологии позволяют подобрать наилучший подход для каждой отдельной проблемы. В общем, обработка в режиме реального времени лучше всего подходит для анализа небольших фрагментов данных, которые меняются или быстро добавляются в систему.

Все эти программы являются фреймворками. Однако есть много других способов вычисления или анализа данных в системе больших данных. Эти инструменты часто подключаются к вышеуказанным фреймворкам и предоставляют дополнительные интерфейсы для взаимодействия с нижележащими уровнями. Например, Apache Hive предоставляет интерфейс хранилища данных для Hadoop, Apache Pig предоставляет интерфейс запросов, а взаимодействия с данными SQL обеспечиваются с помощью Apache Drill, Apache Impala, Apache Spark SQL и Presto. В машинном обучении применяются Apache SystemML, Apache Mahout и MLlib от Apache Spark. Для прямого аналитического программирования, которое широко поддерживается экосистемой данных, используют R и Python.

Визуализация результатов

Часто распознавание тенденций или изменений в данных с течением времени важнее полученных значений. Визуализация данных – один из наиболее полезных способов выявления тенденций и организации большого количества точек данных.

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

Одним из популярных способов визуализации данных является стек Elastic, ранее известный как стек ELK. Logstash используется для сбора данных, Elasticsearch для индексирования данных, а Kibana – для визуализации. Стек Elastic может работать с большими данными, визуализировать результаты вычислений или взаимодействовать с необработанными метриками. Аналогичный стек можно получить, объединив Apache Solr для индексирования форк Kibana под названием Banana для визуализации. Такой стек называется Silk.

Другой технологией визуализации для интерактивной работы в области данных являются документы. Такие проекты позволяют осуществлять интерактивное исследование и визуализацию данных в формате, удобном для совместного использования и представления данных. Популярными примерами этого типа интерфейса являются Jupyter Notebook и Apache Zeppelin.

Читайте также: