Variable size/Get

From Rosetta Code
Task
Variable size/Get
You are encouraged to solve this task according to the task description, using any language you may know.

Demonstrate how to get the size of a variable.

See also: Host introspection

Ada

Ada represents the size of a variable in bits, not bytes like many other languages. <lang ada>Int_Bits : constant Integer := Integer'size; Whole_Bytes : constant Integer := Int_Bits / Storage_Unit; -- Storage_Unit is the number of bits per storage element</lang>

ALGOL 68

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release c.0-9h.tiny

This kind of information is not directly available to the coder. On some implementations this can be manually inferred by using the constant bytes width from the prelude. Alternatively the binary transput can be used to shunt data to a file, and from there the size of resulting file might be calculated. Note that Algol68 has tagged unions, and control structures for arrays, thus the size of these can only be estimated by the coder. Similarly the size of any struct may internally be subject to byte and word alignment.

Not withstanding the above, with ALGOL 68G Revision 1.18 the size of int is not equal to the size of bytes.

Also note that the size of a byte can vary from one CPU to another, c.f. Host_introspection#ALGOL_68 for additional details. <lang algol68>INT i; BYTES b; # typically INT and BYTES are the same size # STRING s:="DCLXVI", [666]CHAR c; print((

 "sizeof INT i =",bytes width, new line,
 "UPB STRING s =",UPB s, new line,
 "UPB []CHAR c =",UPB c, new line

))</lang> Output:

sizeof INT i =        +32
UPB STRING s =         +6
UPB []CHAR c =       +666

AutoHotkey

<lang AutoHotkey>VarSetCapacity(Var, 10240000)  ; allocate 10 megabytes MsgBox % size := VarSetCapacity(Var)  ; 10240000</lang>

C#

<lang csharp> class Program {

   static void Main(string[] args)
   {
       int i = sizeof(int);
       Console.WriteLine(i);
       Console.ReadLine();
   }       

} </lang>

C

<lang c>printf("An int contains %u bytes.\n", sizeof(int));</lang>

C++

Store the size of an int in bytes:

<lang cpp>#include <cstdlib> std::size_t intsize = sizeof(int);</lang>

Note: sizeof can be used without the header <cstdlib>; the latter is only needed for the type std::size_t, which is an alias for whatever type is used to store sizes for the given compiler.

Output the number of bits of an int:

<lang cpp>#include <climits>

  1. include <cstdlib>

std::size_t intbits = CHAR_BITS*sizeof(int);</lang>

Note: the type char is always 1 byte (which, however, need not be 8 bits).

Get the size of a variable in bytes:

<lang cpp>#include <cstdlib> int a = 1; std::size_t a_size = sizeof a;</lang>

Note: Parentheses are needed around types, but not around variables.

Get the size of an expression's type:

<lang cpp>#include <cstdlib> std::size_t size = sizeof (3*6 + 7.5);</lang>

Common Lisp

As with some of the other dynamic languages, we're not concerned with variable size, but rather the size of a value that a variable references. There's not a standard interface for this, but implementations may provide this functionality.

Works with: LispWorks

<lang lisp>(let ((a (cons 1 2))

     (b (make-array 10))
     (c "a string"))
 (list (hcl:find-object-size a)
       (hcl:find-object-size b)
       (hcl:find-object-size c)))</lang>

returns

<lang lisp>(12 48 24)</lang>

However, note that interesting objects are generally composed of several levels of references, often including references to preexisting objects, so what the size should be considered as is often hard to define after the fact. A robust though non-automatic way to determine the “true” memory utilization of some data is to do something like this:

<lang lisp>(let (items)

 (gc) ; name varies by implementation
 (room)
 (dotimes (x 512)
   (push (allocate-something-of-interest) items))
 (gc)
 (room))</lang>

room prints information about current memory usage, but in an implementation-defined format. Take the difference of the relevant numbers, divide by 512, and you have the amount of memory consumed by allocating one additional instance of whatever it is.

D

Every type and variable in D has a property sizeof, which give the size of the type in bytes. eg. <lang d>int i ; writefln(i.sizeof) ; // print 4 int[13] ints1 ; // static integer array of length 13 writefln(ints1.sizeof) ; // print 52 int[] ints2 = new int[13] ; // dynamic integer array, variable length, currently 13 writefln(ints2.sizeof) ; // print 8, all dynamic array has this size writefln(ints2.length) ; // print 13, length is the number of allocated element in aggregated type</lang>

Delphi

<lang delphi>i := sizeof([any variable or structure]);</lang>

Fortran

Works with: Fortran version 90 and later

The intrinsic functions bit_size and digits can be used to find the size of an integer. Bit_size returns the number of bits in an integer while digits returns the number of significant digits in the integer. Because of the use of signed intergers this will be one less than the bit size. Digits can be used on real variables where it returns the number of significant figures in the mantissa. <lang fortran>INTEGER, PARAMETER :: i8 = SELECTED_INT_KIND(2) INTEGER, PARAMETER :: i16 = SELECTED_INT_KIND(4) INTEGER, PARAMETER :: i32 = SELECTED_INT_KIND(8) INTEGER, PARAMETER :: i64 = SELECTED_INT_KIND(16) INTEGER(i8)  :: onebyte = 0 INTEGER(i16) :: twobytes = 0 INTEGER(i32) :: fourbytes = 0 INTEGER(i64) :: eightbytes = 0

WRITE (*,*) BIT_SIZE(onebyte), DIGITS(onebyte)  ! prints 8 and 7 WRITE (*,*) BIT_SIZE(twobytes), DIGITS(twobytes)  ! prints 16 and 15 WRITE (*,*) BIT_SIZE(fourbytes), DIGITS(fourbytes)  ! prints 32 and 31 WRITE (*,*) BIT_SIZE(eightbytes), DIGITS(eightbytes)  ! prints 64 and 63 WRITE (*,*) DIGITS(0.0), DIGITS(0d0)  ! prints 24 and 53</lang>

Go

<lang go>import "unsafe"

unsafe.Sizeof(x)</lang>

Haskell

only works with types that instance Storable: <lang haskell>import Foreign

sizeOf (undefined :: Int) -- size of Int in bytes (4 on mine) sizeOf (undefined :: Double) -- size of Double in bytes (8 on mine) sizeOf (undefined :: Bool) -- size of Bool in bytes (4 on mine) sizeOf (undefined :: Ptr a) -- size of Ptr in bytes (4 on mine)</lang>

IDL

IDL is array based, so its size() function is geared towards that:

<lang idl>arr = intarr(3,4) print,size(arr)

=> prints this
      2           3           4           2          12</lang>

The result means: 2 dimensions in the array, the first dimension has extent 3, the second has extent 4, the elements of the array are 2-byte integers (IDL's default for an "int"), there's a total of 12 elements in the array.

J

In J, the function 7!:5 is analogous to sizeof in C. For example:

<lang j>some_variable =: 42 7!:5<'some_variable'</lang> An advantage of 7!:5 is that it can be used on any name, including functions, operators, etc (i.e. it's not just restricted to variables): <lang j>some_function =: +/ % # 7!:5<'some_function'</lang>

Modula-3

BITSIZE and BYTESIZE are built in functions.

<lang modula3>MODULE Size EXPORTS Main;

FROM IO IMPORT Put; FROM Fmt IMPORT Int;

BEGIN

 Put("Integer in bits: " & Int(BITSIZE(INTEGER)) & "\n");
 Put("Integer in bytes: " & Int(BYTESIZE(INTEGER)) & "\n");

END Size.</lang>

Output:

Integer in bits: 32
Integer in bytes: 4

OCaml

<lang ocaml>(** The result is the size given in word.

 The word size in octet can be found with (Sys.word_size / 8).
 (The size of all the datas in OCaml is at least one word, even chars and bools.)
  • )

let sizeof v =

 let rec rec_size d r =
   if List.memq r d then (1, d) else
   if not(Obj.is_block r) then (1, r::d) else
   if (Obj.tag r) = (Obj.double_tag) then (2, r::d) else
   if (Obj.tag r) = (Obj.string_tag) then (Obj.size r, r::d) else
   if (Obj.tag r) = (Obj.object_tag) ||
      (Obj.tag r) = (Obj.closure_tag)
   then invalid_arg "please only provide datas"
   else
     let len = Obj.size r in
     let rec aux d sum i =
       if i >= len then (sum, r::d) else
       let this = Obj.field r i in
       let this_size, d = rec_size d this in
       aux d (sum + this_size) (i+1)
     in
     aux d (1) 0
 in
 fst(rec_size [] (Obj.repr v))
</lang>

testing in the toplevel: <lang ocaml># sizeof 234 ;; - : int = 1

  1. sizeof 23.4 ;;

- : int = 2

  1. sizeof (1,2);;

- : int = 3

  1. sizeof (2, 3.4) ;;

- : int = 4

  1. sizeof (1,2,3,4,5) ;;

- : int = 6

  1. sizeof [| 1;2;3;4;5 |] ;;

- : int = 6

  1. sizeof [1;2;3;4;5] ;;

- : int = 11

(* because a list is equivalent to *)

  1. sizeof (1,(2,(3,(4,(5,0))))) ;;

- : int = 11

  1. type foo = A | B of int | C of int * int ;;

type foo = A | B of int | C of int * int

  1. sizeof A ;;

- : int = 1

  1. sizeof (B 3) ;;

- : int = 2

  1. sizeof (C(1,2)) ;;

- : int = 3

  1. sizeof true ;;

- : int = 1

  1. sizeof 'A' ;;

- : int = 1

  1. sizeof `some_pvar ;;

- : int = 1

  1. sizeof "" ;;

- : int = 1

  1. sizeof "Hello!" ;;

- : int = 2 (* remember the size is given in words

  (so 4 octets on 32 bits machines) *)
  1. for i=0 to 16 do
   Printf.printf "%d -> %d\n" i (sizeof(String.create i))
 done;;

0 -> 1 1 -> 1 2 -> 1 3 -> 1 4 -> 2 5 -> 2 6 -> 2 7 -> 2 8 -> 3 9 -> 3 10 -> 3 11 -> 3 12 -> 4 13 -> 4 14 -> 4 15 -> 4 16 -> 5 - : unit = ()

  1. sizeof(Array.create 10 0) ;;

- : int = 11

  1. sizeof(Array.create 10 (String.create 20)) ;;

- : int = 16

  1. sizeof(Array.init 10 (fun _ -> String.create 20)) ;;

- : int = 61</lang>

Perl

Works with: Perl version 5.x

<lang perl>use Devel::Size;

my $var = 9384752; my @arr = (1, 2, 3, 4, 5, 6); print size($var); print total_size(@arr);</lang>

PL/I

<lang PL/I> put skip list (SIZE(x)); /* gives the number of bytes occupied by X */

                        /* whatever data type or structure it is.  */

put skip list (CURRENTSIZE(x));

                        /* gives the current number of bytes of X  */
                        /* actually used by such things as a       */
                        /* varying-length string, including its    */
                        /* length field.                           */

</lang>

PicoLisp

In PicoLisp, all variables have the same size (a single cell). Therefore it makes more sense to inspect the size of data structures. This can be done with the 'size' and 'length' functions.

PureBasic

<lang PureBasic>Define a Debug SizeOf(a)

This also works for structured variables</lang>

Python

This information is only easily available for the array type: <lang python>>>> from array import array >>> argslist = [('l', []), ('c', 'hello world'), ('u', u'hello \u2641'), ('l', [1, 2, 3, 4, 5]), ('d', [1.0, 2.0, 3.14])] >>> for typecode, initializer in argslist: a = array(typecode, initializer) print a, '\tSize =', a.buffer_info()[1] * a.itemsize del a


array('l') Size = 0 array('c', 'hello world') Size = 11 array('u', u'hello \u2641') Size = 14 array('l', [1, 2, 3, 4, 5]) Size = 20 array('d', [1.0, 2.0, 3.1400000000000001]) Size = 24 >>></lang> Also:

Works with: Python version 2.6+

<lang python>import sys sys.getsizeof(obj)</lang>

Pop11

From abstract point of view Pop11 variables are bindings between identifiers and values. In concrete terms Pop11 variables store references to values in the heap. Each reference takes one machine word (4 bytes on 32-bit machines and 8 bytes on 64-bit machines). Pop11 identifiers take 3 machine words, but are only needed for "permanent" variables (lexical variables do not need identifiers after compilation). Additionally variable names (words) need space (4 machine for word + space for string corresponding to the word). The bottom line is: variable needs one machine word plus some overhead due to introspection.

Form user point of view more important is space taken by values (size of values referenced by a single variable typically varies during program execution). The datasize function gives amount (in machine words) of space directly used by given value:

<lang pop11>;;; Prints 0 because small integers need no heap storage datasize(12) =>

Prints 3
3 character fits into single machine word, 1 word
for tag, 1 for length

datasize('str') =>

3 element vector takes 5 words
3 for values, 1 for tag, 1 for
length

datasize({1 2 3}) =>

Prints 3 because only first node counts

datasize([1 2 3]) =></lang>

Note that large amount of data my be referenced from given value, but this data is potentially shared, so there is no canonical way to assign it to a single value or variable.

R

object.size gives an estimate of the amount of memory used to store the variable, in (kilo/Mega/Giga) bytes. See also dim, length and nchar for determining the extent of mulitdimensional variables (such as matrices, lists, etc). <lang R># Results are system dependent num <- c(1, 3, 6, 10) object.size(num) # e.g. 56 bytes

  1. Allocating vectors using ':' results in less memory being (reportedly) used

num2 <- 1:4 object.size(num2) # e.g. 40 bytes

  1. Memory shared by objects isn't always counted

l <- list(a=c(1, 3, 6, 10), b=1:4) object.size(l) # e.g. 280 bytes

l2 <- list(num, num2) object.size(l2) # e.g. 128 bytes</lang>

Tcl

Since all variables are ultimately strings in Tcl, this is easy: <lang tcl>string bytelength $var</lang> There is additional overhead per value and per variable, which depends on the architecture that Tcl was built for and the version of Tcl. In 8.5 on a ILP-32 architecture, local variables have an overhead of 8 bytes (without traces) and values have a minimum overhead of 24 bytes (this minimum is achieved for integers that fit in a signed 64-bit integer type or a double-precision float).

Toka

There are two primary data types in Toka, cells and characters. The size of these can be obtained easily:

<lang toka>char-size . cell-size .</lang>

If you load the floating point support, you can also obtain the size of a floating point number:

<lang toka>needs floats float-size .</lang>

All sizes are returned in bytes.

Ursala

The virtual machine represents all code and data as binary trees of cells. The number of cells required for any object can be computed by the built in weight function (or by an equivalent user-defined function), which takes an argument of any type and returns a natural number. Host memory usage for any given object is worst case linear in the weight, but may be considerably less due to sharing (i.e., copying something by copying only a reference to it, which is done automatically and invisibly to the programmer with correct semantics).

An additional facility exists for arbitrary precision floating point numbers, which are based on the mpfr library. The library function mpfr..prec applies to a number in mpfr format and returns the number of bits of precision in the mantissa. Host memory usage is linear plus a small constant. <lang Ursala>#import std

  1. cast %nL

examples = <weight 'hello',mpfr..prec 1.0E+0></lang> output:

<40,160>