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
ActionScript
Requires the debug Flash Player 9.0.115.0 or higher. <lang ActionScript> package {
import flash.display.Sprite; import flash.events.Event; import flash.sampler.getSize; public class VariableSizeGet extends Sprite { public function VariableSizeGet() { if ( stage ) _init(); else addEventListener(Event.ADDED_TO_STAGE, _init); } private function _init(e:Event = null):void { var i:int = 1; var n:Number = 0.5; var s:String = "abc"; var b:Boolean = true; var date:Date = new Date(); trace("An int contains " + getSize(i) + " bytes."); // 4 trace("A Number contains " + getSize(n) + " bytes."); // 8 trace("The string 'abc' contains " + getSize(s) + " bytes."); // 24 trace("A Boolean contains " + getSize(b) + " bytes."); // 4 trace("A Date object contains " + getSize(date) + " bytes."); // 48 } }
} </lang>
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
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>
Babel
In Babel, you can get the raw size with the mu operator and you can also break this down into its components: <lang babel>main:
{ (1 2 (3 4) 5 6) dup mu disp dup nva disp dup npt disp dup nlf disp dup nin disp dup nhref disp dup nhword disp }
disp! : { %d cr << } </lang>
- Output:
38 6 14 6 7 1 4
Note that 38 = 6 + 14 + 6 + 7 + 1 + 4
- mu - Memory Usage
- nva - Number of values (each numeric constant is a value)
- npt - Number of pointers (each cons has two pointers)
- nlf - Number of leaf-arrays (same as the number of values)
- nin - Number of interior arrays (the number of conses)
- nhref - Number of hash-references (nil is a hash-reference)
- nhword - Number of words devoted to storing hash-references (each hash-reference takes up 4 words)
Sizes are relative to the machine-word size.
You can also take the size of an object by first serializing it:
<lang babel>main : { (1 2 (3 4) 5 6) unload size %d << } </lang>
- Output:
38
BASIC
<lang gwbasic>10 REM this only works with strings 20 PRINT LEN(variable$)</lang>
Many BASICs, especially those compatible with QBasic,
can use LEN
to find the size of any variable:
<lang qbasic>DIM a AS INTEGER, b AS LONG, c AS SINGLE, d AS DOUBLE, e AS STRING
PRINT LEN(a), LEN(b), LEN(c), LEN(d), LEN(e)</lang>
- Output:
2 4 4 8 0
Note that when used with a string, LEN
reports the length of the string, not its size in memory.
BASIC typically stores information about the string separately from the string itself, usually immediately before the string itself in memory (but some implementations may store such information elsewhere).
BBC BASIC
A variable's size is implied by its type suffix. The easiest way to determine the size is to use a structure: <lang bbcbasic> DIM bstruct{b&}
DIM istruct{i%} DIM fstruct{f} DIM dstruct{d#} DIM sstruct{s$} PRINT "Size of b& is ";DIM(bstruct{}) PRINT "Size of i% is ";DIM(istruct{}) PRINT "Size of f is ";DIM(fstruct{}) PRINT "Size of d# is ";DIM(dstruct{}) PRINT "Size of s$ is ";DIM(sstruct{})</lang>
Here the size given for the string s$ is for its descriptor, not its contents.
- Output:
Size of b& is 1 Size of i% is 4 Size of f is 5 Size of d# is 8 Size of s$ is 6
C
<lang c>printf("An int contains %u bytes.\n", sizeof(int));</lang>
C#
<lang csharp> class Program {
static void Main(string[] args) { int i = sizeof(int); Console.WriteLine(i); Console.ReadLine(); }
} </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>
- 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>
COBOL
COBOL is by and large a fixed length system, most data types have a size determined by standard.
Some native architecture sizing can be controlled by configuration or will be bound by implementation constraint.
Group items are mostly determined by the data definition, with some variance due to binary sizing and programmer controlled OCCURS DEPENDING ON run time values.
There are run-time functions for LENGTH, BYTE-LENGTH, and a common extension for a LENGTH OF phrase that works at both compile time if possible and at run time when compile time sizing is not determinable.
In COBOL a BINARY-LONG is 32 bits, by definition, and does not change from platform to platform. Same for BINARY-CHAR (1), BINARY-SHORT (2), BINARY-DOUBLE (8), by spec.
POINTER data is one of the few platform dependent fields, and most compilers
provide some way of determining this at compile time, as with the Compiler
Directing Facility >>IF P64 IS SET
, shown here.
<lang COBOL>
identification division. program-id. variable-size-get.
environment division. configuration section. repository. function all intrinsic.
data division. working-storage section. 01 bc-len constant as length of binary-char. 01 fd-34-len constant as length of float-decimal-34. 77 fixed-character pic x(13). 77 fixed-national pic n(13). 77 fixed-nine pic s9(5). 77 fixed-separate pic s9(5) sign trailing separate. 77 computable-field pic s9(5) usage computational-5. 77 formatted-field pic +z(4),9.
77 binary-field usage binary-double. 01 pointer-item usage pointer.
01 group-item. 05 first-inner pic x occurs 0 to 3 times depending on odo. 05 second-inner pic x occurs 0 to 5 times depending on odo-2. 01 odo usage index value 2. 01 odo-2 usage index value 4.
procedure division. sample-main. display "Size of:" display "BINARY-CHAR : " bc-len display " bc-len constant : " byte-length(bc-len) display "FLOAT-DECIMAL-34 : " fd-34-len display " fd-34-len constant : " byte-length(fd-34-len)
display "PIC X(13) field : " length of fixed-character display "PIC N(13) field : " length of fixed-national
display "PIC S9(5) field : " length of fixed-nine display "PIC S9(5) sign separate : " length of fixed-separate display "PIC S9(5) COMP-5 : " length of computable-field
display "ALPHANUMERIC-EDITED : " length(formatted-field)
display "BINARY-DOUBLE field : " byte-length(binary-field) display "POINTER field : " length(pointer-item) >>IF P64 IS SET display " sizeof(char *) > 4" >>ELSE display " sizeof(char *) = 4" >>END-IF
display "Complex ODO at 2 and 4 : " length of group-item set odo down by 1. set odo-2 up by 1. display "Complex ODO at 1 and 5 : " length(group-item)
goback. end program variable-size-get.
</lang>
- Output:
prompt$ cobc -xj variable-size-get.cob -cb_conf=complex-odo:yes -cb_conf=binary-size:1--8 Size of: BINARY-CHAR : 1 bc-len constant : 1 FLOAT-DECIMAL-34 : 16 fd-34-len constant : 2 PIC X(13) field : 13 PIC N(13) field : 26 PIC S9(5) field : 5 PIC S9(5) sign separate : 6 PIC S9(5) COMP-5 : 3 ALPHANUMERIC-EDITED : 000000007 BINARY-DOUBLE field : 000000008 POINTER field : 000000008 sizeof(char *) > 4 Complex ODO at 2 and 4 : +000000007 Complex ODO at 1 and 5 : 000000008
Note the Complex ODO at 2 and 4. It uses the length of phrase, which in this case cannot be detemined at compile time. Internally, this creates a field that happens to cause DISPLAY to treat it as a signed quantity; an implementation detail.
Also note that complex ODO is not an overly common COBOL structure, and many
compilers will not allow it. Where does second-inner
start?
At byte 4 in this example, even when the initial first-inner
is
set at 2. Total size is 7 at first, 3 bytes (2 usable at odo
set
to 2) and 4 for the second-inner
. It can get more complicated
when complex ODO is grouped within groups, so it is not a common practice
in COBOL.
With a change of binary-size compile time configuration from 1--8 to 1-2-4-8:
prompt$ cobc -xj variable-size-get.cob -cb_conf=complex-odo:yes -cb_conf=binary-size:1-2-4-8 ... PIC S9(5) COMP-5 : 4 ...
and the computional field is now allocated (and handled as) 4 bytes, even though it will fit in 3. (Be wary allowing 3 byte binary fields, as they can be a performance hit on some platforms, possibly even leading to SS$_ACCVIO on OpenVMS/Vax systems, for instance). All other fields remain the same size, in this example.
Sizing of data items is both an art and science for COBOL programmers, and the standard goes to great lengths to make sure data field sizes are as deterministic as possible.
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.
<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>
Elixir
When “counting” the number of elements in a data structure, Elixir also abides by a simple rule: the function is named size if the operation is in constant time or length if the operation is linear. <lang elixir>list = [1,2,3] IO.puts length(list) #=> 3
tuple = {1,2,3,4} IO.puts tuple_size(tuple) #=> 4
string = "Elixir" IO.puts String.length(string) #=> 6 IO.puts byte_size(string) #=> 6 IO.puts bit_size(string) #=> 48
utf8 = "○×△" IO.puts String.length(utf8) #=> 3 IO.puts byte_size(utf8) #=> 8 IO.puts bit_size(utf8) #=> 64
bitstring = <<3 :: 2>> IO.puts byte_size(bitstring) #=> 1 IO.puts bit_size(bitstring) #=> 2
map = Map.new([{:b, 1}, {:a, 2}]) IO.puts map_size(map) #=> 2</lang>
Erlang
24> erlang:tuple_size( {1,2,3} ). 3 25> erlang:length( [1,2,3] ). 3 29> erlang:bit_size( <<1:11>> ). 11 30> erlang:byte_size( <<1:11>> ). 2
Fortran
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> More detail: <lang go>package main
import (
"fmt" "reflect" "runtime" "unsafe"
)
func main() {
// unsafe.Sizeof returns the size in bytes. var i int fmt.Println(unsafe.Sizeof(i)) // The size returned is that of the top level object and does not // include any referenced data. A type like string always returns // the same number, the size of the string header. fmt.Println(unsafe.Sizeof("Rosetta")) fmt.Println(unsafe.Sizeof("Code")) // For some untrusted environments, package unsafe is not available // but reflect is. The Size method of a type will return the same value // as unsafe.Sizeof. fmt.Println(reflect.TypeOf("Cod").Size()) // Some sizes are implementation dependent. fmt.Println(runtime.Version(), runtime.GOARCH)
}</lang>
- Output:
8 16 16 16 go1.2 amd64
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>
Icon and Unicon
Icon and Unicon fall into the category of high level languages that don't get close to the machine. As much as possible is done to provide high level and portable interfaces. Two methods are available, one returns the high level size of a value and the other gives information about actual size.
- The unary operator * returns the size of most data types and structures
- integer and real numbers will be coerced to strings
- not defined for files and I/O objects
- for coexpressions it returns the number of results produced
- The keyword &allocated provides information about the actual storage allocated for the data and overhead of each type
- This will show 0 for the assignment of program constants such as strings. Manipulation will be required to produce an allocation.
<lang Icon>record rec0() record rec4(a,b,c,d)
procedure main() # get size
every i := seq(1) do {
a0 := &allocated x := case i of { 1 : "ABCDEFGH" 2 : reverse(x) 10 : &digits 11 : x--x 20 : [] 21 : [1,2] 22 : [1,2,3] 30 : set() 31 : set("X") 32 : set("A","B") 40 : table(1) 50 : rec0() 51 : rec4() 60 : create seq(1) 99 : break default : next } a1 := &allocated write("type=",type(x)," *x=",*x," bytes allocated=",a1-a0) }
end</lang>
- Output:
type=string *x=8 bytes allocated=0 type=string *x=8 bytes allocated=8 type=cset *x=10 bytes allocated=0 type=cset *x=0 bytes allocated=40 type=list *x=0 bytes allocated=116 type=list *x=2 bytes allocated=68 type=list *x=3 bytes allocated=76 type=set *x=0 bytes allocated=104 type=set *x=1 bytes allocated=124 type=set *x=2 bytes allocated=144 type=table *x=0 bytes allocated=112 type=rec0 *x=0 bytes allocated=16 type=rec4 *x=4 bytes allocated=48 type=co-expression *x=0 bytes allocated=96
The results above illustrate both measurements. I believe that an empty list is allocated with growth room for 8 elements which explains why it would require more storage than a list of 1 or 2 elements.
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>
Julia
<lang julia>julia> sizeof(Int8) 1
julia> t = 1 1
julia> sizeof(t) 8</lang> (The last line returns 4 on a 32-bit machine or when Julia is compiled in 32-bit mode.)
Lasso
<lang Lasso>local( mystring = 'Hello World', myarray = array('one', 'two', 3), myinteger = 1234 )
// size of a string will be a character count
- mystring -> size
'
'
// size of an array or map will be a count of elements
- myarray -> size
'
'
// elements within an array can report size
- myarray -> get(2) -> size
'
'
// integers or decimals does not have sizes //#myinteger -> size // will fail // an integer can however be converted to a string first string(#myinteger) -> size</lang> ->11
3
3
4
Mathematica
<lang Mathematica>ByteCount["somerandomstring"]</lang>
- Output:
64
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
Nim
<lang nim>echo "An int contains ", sizeof(int), " bytes."</lang>
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
- sizeof 23.4 ;;
- : int = 2
- sizeof (1,2);;
- : int = 3
- sizeof (2, 3.4) ;;
- : int = 4
- sizeof (1,2,3,4,5) ;;
- : int = 6
- sizeof [| 1;2;3;4;5 |] ;;
- : int = 6
- sizeof [1;2;3;4;5] ;;
- : int = 11
(* because a list is equivalent to *)
- sizeof (1,(2,(3,(4,(5,0))))) ;;
- : int = 11
- type foo = A | B of int | C of int * int ;;
type foo = A | B of int | C of int * int
- sizeof A ;;
- : int = 1
- sizeof (B 3) ;;
- : int = 2
- sizeof (C(1,2)) ;;
- : int = 3
- sizeof true ;;
- : int = 1
- sizeof 'A' ;;
- : int = 1
- sizeof `some_pvar ;;
- : int = 1
- sizeof "" ;;
- : int = 1
- sizeof "Hello!" ;;
- : int = 2 (* remember the size is given in words
(so 4 octets on 32 bits machines) *)
- 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 = ()
- sizeof(Array.create 10 0) ;;
- : int = 11
- sizeof(Array.create 10 (String.create 20)) ;;
- : int = 16
- sizeof(Array.init 10 (fun _ -> String.create 20)) ;;
- : int = 61</lang>
ooRexx
In ooRexx, all variables are just untyped references to objects, so there is no inherent or visible variable size.
For character strings see Rexx (except for the d= example). Other objects have a "required string value" used, e.g., in Say object. The "size" of objects is indeed hidden and unvisible. --Walterpachl 05:51, 1 October 2012 (UTC)
PARI/GP
In GP, this gets the size of the variable x in bytes: <lang parigp>sizebyte(x)</lang>
In PARI,
<lang C>lg(x)</lang>
returns the length of the variable x in words. gsizebyte
and gsizeword
are also available.
Pascal
same as Delphi: <lang delphi>i := sizeof([any variable or structure]);</lang>
Perl
<lang perl>use Devel::Size;
my $var = 9384752; my @arr = (1, 2, 3, 4, 5, 6); print size($var); print total_size(@arr);</lang>
Perl 6
Perl 6 tries to avoid generic terms such as "size" and "length", instead providing methods that are expressed in terms of the units appropriate to the abstraction level. <lang perl6># Textual strings are measured in characters (graphemes) my $string = "abc";
- Arrays are measured in elements.
say $string.chars; # 3 my @array = 1..5; say @array.elems; # 5
- Buffers may be viewed either as a byte-string or as an array of elements.
my $buffer = '#56997; means "four dragons".'.encode('utf8'); say $buffer.bytes; # 26 say $buffer.elems; # 26</lang> Perl's Int type is arbitrary sized, and therefore the abstract size of the integer depends on how many bits are needed to represent it. While the internal representation is likely to be "chunky" by 32 or 64 bits, this is considered an implementation detail and is not revealed to the programmer.
Native types such as int64 or num32 are of fixed size; Perl 6 supports representational polymorphism of such types (and compositions of such types) through a pluggable meta-object protocol providing "knowhow" objects for the various representations. Currently the NativeHOW knowhow may be interrogated for the bit sizes of native types, but this is officially outside the purview of the language itself (so far).
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.
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>
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.
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:
<lang python>import sys sys.getsizeof(obj)</lang>
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
- Allocating vectors using ':' results in less memory being (reportedly) used
num2 <- 1:4 object.size(num2) # e.g. 40 bytes
- 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>
Racket
<lang racket>
- lang racket
(require ffi/unsafe) (define-syntax-rule (sizes t ...)
(begin (printf "sizeof(~a) = ~a\n" 't (ctype-sizeof t)) ...))
(sizes _byte _short _int _long _llong _float _double) </lang>
REXX
In REXX, you simply set a variable to a value (it could be an expression);
the value's length is the size of the variable's value.
<lang rexx>/*REXX program demonstrates (see the penultimate statement) how to */
/* to find the size (length) of the value of a REXX variable. */
/*REXX doesn't reserve any storage for any variables, as all variables */ /*are stored as character strings, including boolean. Storage is */ /*obtained as necessary when REXX variables are assigned (or reassigned)*/
a = 456 /*length of A is 3 */ b = "heptathlon" /*length of B is 10 */ c = "heptathlon (7 events)" /*length of C is 21 */ d = /*length of D is 0 */ d = "" /*same as above. */ d = left('space junk' ,0) /*same as above. */ d = /*same as above. */ e = 99-9 /*length of E is 2 (e=90) */ f = copies(a,100) /*length of F is 300 (a=456)*/ g.1 = -1 /*length of G.1 is 2 */ g.2 = -1.0000 /*length of G.2 is 7 */
/*length of HHH is 3 */
/*Note that when a REXX variable */ /*isn't SET, then the value of it*/ /*is the uppercased name itself, */ /*so in this case (upper): HHH */
something = copies(a, random(100)) /*length is something, all right,*/
/*could be 3 to 300 bytes, by gum*/
thingLen = length(something) /*use LENGTH bif to find its len.*/ say 'length of SOMETHING =' thingLen /*display the length of SOMETHING*/
/*┌────────────────────────────────────────────────────────────────────┐
│ Note that the variable's data (value) isn't the true cost of the │ │ size of the variable's value. REXX also keeps the name of │ │ the (fully qualified) variable as well. │ │ │ │ Most REXX interpreters keep (at a miminum): │ │ │ │ ∙ a four-byte field which contains the length of the value │ │ ∙ a four-byte field which contains the length of the var name │ │ ∙ an N-byte field which contains the name of the variable │ │ ∙ an X-byte field which contains the variable's value │ │ ∙ a one-byte field which contains the status of the variable │ │ │ │ [Note that PC/REXX uses a two-byte field for the first two fields] │ │ │ │ │ │ Consider the following two DO loops assigning a million variables: │ │ │ │ do j=1 to 1000000 │ │ integer_numbers.j=j │ │ end │ │ ════════ and ════════ │ │ do k=1 to 1000000 │ │ #.k=k │ │ end │ │ │ │ The "j" loop uses 35,777,792 bytes for the compound variables, │ │ The "k" loop uses 21,777,792 bytes for the compound variables, │ │ (excluding the DO loop indices [j and k] themselves). │ └────────────────────────────────────────────────────────────────────┘*/</lang>
Ruby
Almost all objects in Ruby (MRI) take 40 bytes (on a x64 machine) initially. Sometimes this is enough to store the entire object, sometimes additional memory has to be allocated. For strings that is the case if they are longer than 23 chars. The additional memory can be retrieved using 'ObjectSpace':
<lang ruby> require 'objspace'
p ObjectSpace.memsize_of("a"*23) #=> 0 p ObjectSpace.memsize_of("a"*24) #=> 25 p ObjectSpace.memsize_of("a"*1000) #=> 1001 </lang>
Scala
<lang Scala> def nBytes(x: Double) = ((Math.log(x) / Math.log(2) + 1e-10).round + 1) / 8
val primitives: List[(Any, Long)] = List((Byte, Byte.MaxValue), (Short, Short.MaxValue), (Int, Int.MaxValue), (Long, Long.MaxValue))
primitives.foreach(t => println(f"A Scala ${t._1.toString.drop(13)}%-5s has ${nBytes(t._2)} bytes"))</lang>
- Output:
A Scala Byte has 1 bytes A Scala Short has 2 bytes A Scala Int has 4 bytes A Scala Long has 8 bytes
Swift
<lang swift>sizeofValue(x)</lang> More detail: <lang swift>// sizeof and sizeofValue return the size in bytes. println(sizeof(Int)) var i: Int = 42 println(sizeofValue(i)) // The size returned is that of the top level value and does not // include any referenced data. A type like String always returns // the same number, the size of the String struct. println(sizeofValue("Rosetta")) println(sizeofValue("Code"))}</lang>
- Output:
8 8 24 24
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).
However, it is usual to not think in terms of the low-level size of a value; instead, concepts such as the length of the string (string length
), list (llength
) or dictionary (dict size
) are used.
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.
TUSCRIPT
<lang tuscript> $$ MODE TUSCRIPT,{} string="somerandomstring" size=SIZE(string) length=LENGTH(string)
PRINT "string: ",string PRINT "has size: ",size PRINT "and length: ",length </lang>
- Output:
string: somerandomstring has size: 1 and length: 16
UNIX Shell
<lang sh># In the shell all variables are stored as strings, so we use the same technique
- as for finding the length of a string:
greeting='Hello, world!' greetinglength=`printf '%s' "$greeting" | wc -c` echo "The greeting is $greetinglength characters in length"</lang>
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
- cast %nL
examples = <weight 'hello',mpfr..prec 1.0E+0></lang>
- Output:
<40,160>
Vala
<lang vala> void main(){
ulong x = sizeof(int); // returns # of bytes used to store an int // is returned as a ulong, but could be typecasted to int with: int x = (int) sizeof(int) stdout.printf("%lu\n", x);
} </lang>
XPL0
This ugly piece of code may be required because there is currently no 'sizeof' operator (at least not in the DOS version, but it is in the Windows version). This is not a big problem since there are only two data types, integer and real; thus there are only two sizes to keep track of, 4 and 8 bytes. However, there are 16-bit versions of the compilers that have 2-byte integers, and a program that runs in both the 16- and 32-bit versions usually defines a constant (typically called "IntSize" = 2 or 4) at the beginning of the program to deal with the different sizes. A common situation where this arises is when allocating memory for dynamic integer arrays using the Reserve intrinsic.
<lang XPL0>include c:\cxpl\codes; int Size; int A, B; real X, Y; [Size:= addr B - addr A; IntOut(0, Size); CrLf(0); Size:= addr Y - addr X; IntOut(0, Size); CrLf(0); ]</lang>
- Output:
4 8
zkl
<lang zkl>(123).len() //-->1 (byte) (1234567890).len() //-->4 (bytes) "this is a test".len() //-->14 L(1,2,3,4).len() //-->4 Dictionary("1",1, "2",2).len() //-->2 (keys) Data(0,Int,1,2,3,4).len() //-->4 (bytes) Data(0,String,"1","2","3","4").len() //-->8 bytes (ASCIIZ)</lang>
Put the data into a variable, same results: a:=123; a.len() --> 1
There is also a size property which returns the size of the underlying [implementation] data structure.
- Programming Tasks
- Type System
- AWK/Omit
- Clojure/Omit
- E/Omit
- Gnuplot/Omit
- Groovy/Omit
- GUISS/Omit
- Java/Omit
- JavaScript/Omit
- LaTeX/Omit
- Logtalk/Omit
- Make/Omit
- Maxima/Omit
- NetRexx/Omit
- PlainTeX/Omit
- XSLT/Omit
- Unlambda/Omit
- ActionScript
- Ada
- ALGOL 68
- AutoHotkey
- Babel
- BASIC
- BBC BASIC
- C
- C sharp
- C++
- COBOL
- Common Lisp
- D
- Delphi
- Elixir
- Erlang
- Fortran
- Go
- Haskell
- Icon
- Unicon
- IDL
- J
- Julia
- Lasso
- Mathematica
- Modula-3
- Nim
- OCaml
- OoRexx
- PARI/GP
- Pascal
- Perl
- Perl 6
- PicoLisp
- PL/I
- Pop11
- PureBasic
- Python
- R
- Racket
- REXX
- Ruby
- Scala
- Swift
- Tcl
- Toka
- TUSCRIPT
- UNIX Shell
- Ursala
- Vala
- XPL0
- Zkl