2015-04-20 3 views
4

Согласно этой презентации (http://oud.ocaml.org/2012/slides/oud2012-paper13-slides.pdf, PDF страницы 4), структурирует следующие два данных используют различное количество памятиПочему продукт использует больше памяти, чем запись?

type t1 = { f1: float; f2:float};; 
type t2 = (float * float);; 

И t1 использовать меньше памяти, чем t2, может кто-нибудь объяснить мне, почему это так?

+0

'float * float' не равномерно использует больше памяти, чем записи/массивы. В 32-битной архитектуре 'let zero = 0.0 in (zero, zero)' использует меньше памяти, чем '{f1 = ноль; f2 = zero} ' –

+1

@PascalCuoq, это интересная загадка! Вы опубликуете ответ, почему это так? – ivg

ответ

7

19.3.3 из http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html#sec425 говорит:

Массивы чисел с плавающей точкой (тип поплавка массив) имеют особый, распакованный, более эффективное представление. Эти массивы представлены указателями на блоки с тегом Double_array_tag.

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

https://realworldocaml.org/v1/en/html/memory-representation-of-values.html также является очень хорошей документацией, которая объясняет внутреннее представление значений OCaml.

+0

Чистый и хорошо документированный ответ, браво! –

4

В дополнение к camlspotter ответить на несколько разъясняющие примечания:

  1. В общих записей, массивов и кортежей используют один и тот же объем памяти.
  2. Исключением являются некоторые составные структуры данных с использованием float. По умолчанию каждый поплавок помещается в бокс, то есть отображается не как мгновенное значение, а как указатель на выделенное значение с плавающей запятой двойной точности. OCaml оптимизирует поплавковые записи и массивы для хранения данных напрямую, без двойного бокса.
  3. Это не работает для полиморфных записей, например, float ref, то есть под капотом запись типа a ref = {mutable contents : 'a} по-прежнему занимает дополнительное пространство, то есть оно является указателем на запись, содержащую указатель на слово. Но, если вы определяете, type float_ref = {mutable float_contents : float} это будет указатель на запись, содержащую непосредственно значение float.
Смежные вопросы