Declaring 'long' over 'int' in Java - java

If int is enough for a field, and if I use long for some reason, would that cost me more memory?

In Java, yes, a long is 8 bytes wide and an integer is 4 bytes wide. This Java tutorial goes over the primitive data types. If you multiply the number of allocations by a certain amount (say, if you're allocating five million of these variables), the difference becomes more than negligible. For the average usage, however, it doesn't matter as much.
(You're already using Java, memory's kind of all over the place anyway.)
In native languages, there's a performance consideration; a 32-bit value can be held in a single register on a 32-bit architecture but not a 64-bit value; on 64-bit architectures, obviously, it can. I'm not sure what kind of optimization Java does on its native integers, but this might be true in its runtime as well. There's alignment issues to worry about, as well -- you see this more with using shorts and bytes, though.
Best practice would be to use the type you need. If the value will never be over 2^31, don't use a long.

Assuming from your previous questions that you mean to ask this in the scope of Java, the int data type is four bytes and the long data type is eight bytes.
However, whether the difference in size actually means a difference in memory usage depends on the situation.
If it's a local variable, it's allocated on the stack. As the stack is already allocated, using more stack space will not use more memory, provided of course that you don't exhaust the stack.
If it a member of a class, it will depend on how the members are aligned. Sometimes members are not stacked compactly in memory, but padding is used so that some members start at an even address. If you for example have a byte and an int in a class, there will likely be three bytes of padding between them so that the int starts at the next address divisible by four.

intis 32 bit and long is 64 bit. long takes twice as much memory (which is pretty insignificant for most applications).

long in Java is 64bit, and int is 32bit, so obviously longs uses more memory (8 bytes instead of 4 bytes).

ifwdev guessed correctly. Java defines an int as a 32-bit signed integer, and a long as a 64-bit signed integer. If you declare a variable as a long, then yes, it will take twice as much memory as the same variable declared as an int. In general, int is typically the "default" numeric type, even for values that could be contained in smaller types like a short. Unless you have a particular reason for requiring values greater than 2^31-1, use an int.

...would that cost me more memory?
You'll be using twice as memory
Before worrying about if you're using more memory or not, you should profile.
To use 1 megabyte extra of ram using long rather than int you'll have to declare: 262,144 long variables (or use them indirectly in your program ).
So if for some reason you declare one or two long variables when int's should be used, you'll be using 4 or 8 bytes more of memory. Not too much to worry about ( I mean, there might be worst memory problems in your app )
Taken from the Java Tutorial here's the definition of int and long
int: The int data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive). For integral values, this data type is generally the default choice unless there is a reason (like the above) to choose something else. This data type will most likely be large enough for the numbers your program will use, but if you need a wider range of values, use long instead.
long: The long data type is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). Use this data type when you need a range of values wider than those provided by int.
But remember: "Premature optimization is the root of all evil" according to Donald Knuth ( according to me Copy/Paste is the root of all evil though )

If you know your data will fit in a specific data type (say short int in C), the only reason to use a bigger one is performance right? And if that's your goal, regardless of how marginal your performance gain is, as a general rule of thumb you want to use a size that matches your architecture's size (so for a normal 32-bit target system, you'd use a 32-bit type).
If you target more than one system, you can use a data type that matches the most often used one.

Related

Java - operations on native short always return int, why? and how? [duplicate]

Why does the Java API use int, when short or even byte would be sufficient?
Example: The DAY_OF_WEEK field in class Calendar uses int.
If the difference is too minimal, then why do those datatypes (short, int) exist at all?
Some of the reasons have already been pointed out. For example, the fact that "...(Almost) All operations on byte, short will promote these primitives to int". However, the obvious next question would be: WHY are these types promoted to int?
So to go one level deeper: The answer may simply be related to the Java Virtual Machine Instruction Set. As summarized in the Table in the Java Virtual Machine Specification, all integral arithmetic operations, like adding, dividing and others, are only available for the type int and the type long, and not for the smaller types.
(An aside: The smaller types (byte and short) are basically only intended for arrays. An array like new byte[1000] will take 1000 bytes, and an array like new int[1000] will take 4000 bytes)
Now, of course, one could say that "...the obvious next question would be: WHY are these instructions only offered for int (and long)?".
One reason is mentioned in the JVM Spec mentioned above:
If each typed instruction supported all of the Java Virtual Machine's run-time data types, there would be more instructions than could be represented in a byte
Additionally, the Java Virtual Machine can be considered as an abstraction of a real processor. And introducing dedicated Arithmetic Logic Unit for smaller types would not be worth the effort: It would need additional transistors, but it still could only execute one addition in one clock cycle. The dominant architecture when the JVM was designed was 32bits, just right for a 32bit int. (The operations that involve a 64bit long value are implemented as a special case).
(Note: The last paragraph is a bit oversimplified, considering possible vectorization etc., but should give the basic idea without diving too deep into processor design topics)
EDIT: A short addendum, focussing on the example from the question, but in an more general sense: One could also ask whether it would not be beneficial to store fields using the smaller types. For example, one might think that memory could be saved by storing Calendar.DAY_OF_WEEK as a byte. But here, the Java Class File Format comes into play: All the Fields in a Class File occupy at least one "slot", which has the size of one int (32 bits). (The "wide" fields, double and long, occupy two slots). So explicitly declaring a field as short or byte would not save any memory either.
(Almost) All operations on byte, short will promote them to int, for example, you cannot write:
short x = 1;
short y = 2;
short z = x + y; //error
Arithmetics are easier and straightforward when using int, no need to cast.
In terms of space, it makes a very little difference. byte and short would complicate things, I don't think this micro optimization worth it since we are talking about a fixed amount of variables.
byte is relevant and useful when you program for embedded devices or dealing with files/networks. Also these primitives are limited, what if the calculations might exceed their limits in the future? Try to think about an extension for Calendar class that might evolve bigger numbers.
Also note that in a 64-bit processors, locals will be saved in registers and won't use any resources, so using int, short and other primitives won't make any difference at all. Moreover, many Java implementations align variables* (and objects).
* byte and short occupy the same space as int if they are local variables, class variables or even instance variables. Why? Because in (most) computer systems, variables addresses are aligned, so for example if you use a single byte, you'll actually end up with two bytes - one for the variable itself and another for the padding.
On the other hand, in arrays, byte take 1 byte, short take 2 bytes and int take four bytes, because in arrays only the start and maybe the end of it has to be aligned. This will make a difference in case you want to use, for example, System.arraycopy(), then you'll really note a performance difference.
Because arithmetic operations are easier when using integers compared to shorts. Assume that the constants were indeed modeled by short values. Then you would have to use the API in this manner:
short month = Calendar.JUNE;
month = month + (short) 1; // is july
Notice the explicit casting. Short values are implicitly promoted to int values when they are used in arithmetic operations. (On the operand stack, shorts are even expressed as ints.) This would be quite cumbersome to use which is why int values are often preferred for constants.
Compared to that, the gain in storage efficiency is minimal because there only exists a fixed number of such constants. We are talking about 40 constants. Changing their storage from int to short would safe you 40 * 16 bit = 80 byte. See this answer for further reference.
The design complexity of a virtual machine is a function of how many kinds of operations it can perform. It's easier to having four implementations of an instruction like "multiply"--one each for 32-bit integer, 64-bit integer, 32-bit floating-point, and 64-bit floating-point--than to have, in addition to the above, versions for the smaller numerical types as well. A more interesting design question is why there should be four types, rather than fewer (performing all integer computations with 64-bit integers and/or doing all floating-point computations with 64-bit floating-point values). The reason for using 32-bit integers is that Java was expected to run on many platforms where 32-bit types could be acted upon just as quickly as 16-bit or 8-bit types, but operations on 64-bit types would be noticeably slower. Even on platforms where 16-bit types would be faster to work with, the extra cost of working with 32-bit quantities would be offset by the simplicity afforded by only having 32-bit types.
As for performing floating-point computations on 32-bit values, the advantages are a bit less clear. There are some platforms where a computation like float a=b+c+d; could be performed most quickly by converting all operands to a higher-precision type, adding them, and then converting the result back to a 32-bit floating-point number for storage. There are other platforms where it would be more efficient to perform all computations using 32-bit floating-point values. The creators of Java decided that all platforms should be required to do things the same way, and that they should favor the hardware platforms for which 32-bit floating-point computations are faster than longer ones, even though this severely degraded PC both the speed and precision of floating-point math on a typical PC, as well as on many machines without floating-point units. Note, btw, that depending upon the values of b, c, and d, using higher-precision intermediate computations when computing expressions like the aforementioned float a=b+c+d; will sometimes yield results which are significantly more accurate than would be achieved of all intermediate operands were computed at float precision, but will sometimes yield a value which is a tiny bit less accurate. In any case, Sun decided everything should be done the same way, and they opted for using minimal-precision float values.
Note that the primary advantages of smaller data types become apparent when large numbers of them are stored together in an array; even if there were no advantage to having individual variables of types smaller than 64-bits, it's worthwhile to have arrays which can store smaller values more compactly; having a local variable be a byte rather than an long saves seven bytes; having an array of 1,000,000 numbers hold each number as a byte rather than a long waves 7,000,000 bytes. Since each array type only needs to support a few operations (most notably read one item, store one item, copy a range of items within an array, or copy a range of items from one array to another), the added complexity of having more array types is not as severe as the complexity of having more types of directly-usable discrete numerical values.
If you used the philosophy where integral constants are stored in the smallest type that they fit in, then Java would have a serious problem: whenever programmers write code using integral constants, they have to pay careful attention to their code to check if the type of the constants matter, and if so look up the type in the documentation and/or do whatever type conversions are needed.
So now that we've outlined a serious problem, what benefits could you hope to achieve with that philosophy? I would be unsurprised if the only runtime-observable effect of that change would be what type you get when you look the constant up via reflection. (and, of course, whatever errors are introduced by lazy/unwitting programmers not correctly accounting for the types of the constants)
Weighing the pros and the cons is very easy: it's a bad philosophy.
Actually, there'd be a small advantage. If you have a
class MyTimeAndDayOfWeek {
byte dayOfWeek;
byte hour;
byte minute;
byte second;
}
then on a typical JVM it needs as much space as a class containing a single int. The memory consumption gets rounded to a next multiple of 8 or 16 bytes (IIRC, that's configurable), so the cases when there are real saving are rather rare.
This class would be slightly easier to use if the corresponding Calendar methods returned a byte. But there are no such Calendar methods, only get(int) which must returns an int because of other fields. Each operation on smaller types promotes to int, so you need a lot of casting.
Most probably, you'll either give up and switch to an int or write setters like
void setDayOfWeek(int dayOfWeek) {
this.dayOfWeek = checkedCastToByte(dayOfWeek);
}
Then the type of DAY_OF_WEEK doesn't matter, anyway.
Using variables smaller than the bus size of the CPU means more cycles are necessary. For example when updating a single byte in memory, a 64-bit CPU needs to read a whole 64-bit word, modify only the changed part, then write back the result.
Also, using a smaller data type requires overhead when the variable is stored in a register, since the behavior of the smaller data type to be accounted for explicitly. Since the whole register is used anyways, there is nothing to be gained by using a smaller data type for method parameters and local variables.
Nevertheless, these data types might be useful for representing data structures that require specific widths, such as network packets, or for saving space in large arrays, sacrificing speed.

Why not use long for all integer values

In my Java class we have just learned about of each of the following primitive data types:
byte
short
int
long
Since the long data type contains the most bits, wouldn't it make sense to exclusively use the long data type to avoid restrictions?
Questions
Is there a particular downside to only using the long data type?
Does it make sense to use for example, an int data type, instead of a long data type?
Does it make sense to use for example, an int data type, instead of a long data type?
ABSOLUTELY YES.
MEMORY / DISK USAGE
Using only one variable or two you won't see difference of performance, but when apps grow it will increase your app speed.
Check this question for further info.
Also looking to Oracle primitive type documentation you can see some advices and the memory usage:
type memory usage recommended for
------- --------------- ---------------------------------------------------
byte 8-bit signed The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters.
short 16-bit signed same as byte
int 32-bit signed
long 64-bit Use this data type when you need a range of values wider than those provided by int
float Use a float (instead of double) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency.
byte:
The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters.
short:
The short data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). As with byte, the same guidelines apply: you can use a short to save memory in large arrays, in situations where the memory savings actually matters.
int:
By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -2³¹ and a maximum value of 2³¹-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2³²-1.
long:
The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -2⁶³ and a maximum value of 2⁶³-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2⁶⁴-1. Use this data type when you need a range of values wider than those provided by int.
float:
The float data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. As with the recommendations for byte and short, use a float (instead of double) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency.
CODE READABILITY
Also, it will clarify your mind and your code, lets say, you have a variable that represents the ID of an object, this object ID will never use decimals, so, if you see in your code:
int id;
you will now for sure how this ID will look, otherwise
double id;
wont.
Also, if you see:
int quantity;
double price;
you will know quantity won't allow decimals (only full objects) but price will do... That makes your job (and others programmers will read your code) easier.
Apart from the Range (the min and max value that can be stored in any particular data type) there is another aspect and that is size of the variable.
You must be aware of the following too:
byte = 1 byte
short = 2 bytes
int = 4 bytes
long = 8 bytes
So using long variable means you are allocating 8 bytes of memory to it.
Something like,
long var = 1000L
does not show efficient use of memory. What if you got GBs of RAM these days does not mean we should waste it.
Simple point I want to make is, more efficient use of memory, faster will be the app.
Performance in memory need and speed would make long expensive.
However there is one other advantage of int: one too easily mixes with int subexpressions, and may loose long info when combining operations wrong. A bit shift left of 50 actually doing 18 and so on. Using only numbers with an L postfix would be one measure. Also long may serve as an overflow capture for int multiplication and other such operations, where for long detecting an overflow is all you can do.
Note that for int "all" operations of byte and short are propagating to int.

What Primitive To Use In Java

I am a little confused on when to use what primitives. If I am defining a number, how do I know what to use byte, short, int, or long? I know they are different bytes, but does that mean that I can only use one of them for a certain number?
So simply, my question is, when do I use each of the four primitives listed above?
If I am lets say defining a number, how do I know what to use byte, short, int, or long?
Depending on your use-case. There's no huge penalty to using an int as opposed to a short, unless you have billions of numbers. Simply consider the range a variable might use. In most cases it is reasonable to use int, whose range is -2,147,483,648 to 2,147,483,647, while long handles numbers in the range of +/- 9.22337204*1018. If you aren't sure, long won't specifically hurt.
The only reasons you might want to use byte specifically is if you are storing byte data such as parts of a file, or are doing something like network communication or serialization where the number of bytes is important. Remember that Java's bytes are also signed (-128 to 127). Same for short--might be useful to save 2GB of memory for a billion-element array, but not specifically useful for much other than, again, serialization with a specific byte alignment.
does that mean that I can only use one of them for a certain number?
No, you can use any that is large enough to handle that number. Of course, decimal values need a double or a float--double is usually ideal due to its higher precision and few drawbacks. Some libraries (e.g. 3D drawing) might use floats however. Remember that you can cast numeric types (e.g. (byte) someInt or (float) functionReturningADouble();
A byte can be a number from -128 to 127
A short can be a number from -32,768 to 32,767
An int can be from -2^32 to 2^32 - 1
A long is -2^63 to 2^63 - 1
Usually unless space is an issue an int is fine.
In order to use a primitive you need to know the data range of the number stored in it. This depends heavily on the thing that you are modeling:
Use byte when your number is in the range [-128..127]
Use short when your number is in the range [-32768..32767]
Use int when your number is in the range [-231..231-1]
Use long when your number is in the range [-263..263-1]
In addition, byte data type is used for representing "raw" binary data, in which case it is not used like a number.
When you want an unlimited range, use BigInteger. This flexibility comes at a cost: operations on BigInteger can be orders of magnitude more expensive than identical operations on primitives.
Do you know what values your variable will potentially hold?
If it will be between -128 and 127, use a byte.
If it will be between -32,768 and 32,767, use a short.
If it will be between -2^32 and 2^32 - 1, use an int.
If it will be between -2^63 and 2^63 - 1, use a long.
Generally an int will be fine for most cases, but you might use a byte or a short if memory is a concern, or a long if you need larger values.
Try writing a little test program. What happens when you put a value that's too large in one of these types of variables?
Source: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
See also: the year 2038 problem
The general guidance should definitely be: If you don't have any good reason to pick a specific primitive, pick int.
This has at least three advantages:
Every kind of arithmetic or logical operation will return an int. Hence if you use anything smaller you will have to cast a lot to actually assign values back.
It's the accepted standard for "some number". If you pick anything else, other developers will wonder about the reasons.
It will be the most efficient, although it's likely that the performance difference from using anything else will be minuscule.
That said if you have an array of millions of elements yes you definitely should figure out what primitive fits the input range - I refer you to the other answers for a summary of how large each one is.
#dasblinkenlight
When you are working for large project, you need to optimize the code for each requirement. Apparently you would reduce the memory occupied by the project.
Hence using int, short, long, byte plays a vital role in terms of optimising the memory. When the interger holds a 1 digit value then you declare the integer with int or short, but you can still choose long,float and double technically but to become a good programmer you can try to follow standards.
Byte - Its 8 bit. So it can hold a value from -128 to 127.
short: Its 32 bit. so -32,768 and a maximum value of 32,767
Long- Its 64 bit. -2 (power of) 63 and a maximum value of 2(power of)63-1
float and double- for large decimal values.
Boolean for Yes or No decesions- can hold a value of 1 or 0
Char for characters.
Hope this answer helps you.

I want to store a number between 0 and 100 in a variable - should I use an INT or a BYTE and why?

I know this is a n00b question but I want to define a variable with a value between 0 and 100 in JAVA. I can use INT or BYTE as data types - but which one would be the best to use. And why?(benefits?)
Either int or byte would work for storing a number in that range.
Which is best depends on what you are aiming to do.
If you need to store lots of these numbers in an array, then a byte[] will take less space than an int[] with the same length.
(Surprisingly) a byte variable takes the same amount of space as a int ... due to the way that the JVM does the stack frame / object frame layout.
If you are doing lots of arithmetic, etc using these values, then int is more convenient than byte. In Java, arithmetic and bitwise operations automatically promote the operands to int, so when you need to assign back to a byte you need to use a (byte) type-cast.
Use byte datatype to store value between -128 to 127
I think since you have used 0.00 with decimals, this means you want to allow decimals.
The best way to do this is by using a floating point type: double or float.
However, if you don't need decimals, and the number is always an integer, you can use either int or byte. Byte can hold anything up to +127 or down to -128, and takes up much less space than an int.
with 32-bit ints on your system, your byte would take up 1/4 of the space!
The disadvantages are that you have to be careful when doing arithmetic on bytes - they can overflow, and cause unexpected results if they go out of range.
If you are using basic IO functions, like creating sounds or reading old file formats, byte is invaluable. But watch out for the sign convention: negative has the high-order bit set. However when doing normal numerical calculations, I always use int, since it allows easy extension to larger values if needed, and 32-bit cpus there is minimal speed cost really. Only thing is if you are storing a large quantity of them.
Citing Primitive Data Types:
byte: The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation.
int: The int data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive). For integral values, this data type is generally the default choice unless there is a reason (like the above) to choose something else. This data type will most likely be large enough for the numbers your program will use, but if you need a wider range of values, use long instead.
Well it depends on what you're doing... out of the blue like that I would say use int because it's a standard way to declare an integer. But, if you do something specific that require memory optimization than maybe byte could be better in that case.
Technically, neither one is appropriate--if you need to store the decimal part, you want a float.
I'd personally argue that unless you're actually getting into resource-constrained issues (embedded system, big data, etc.) your code will be slightly clearer if you go with int. Good style is about being legible to people, so indicating that you're working with integers might make more sense than prematurely optimizing and thus forcing future maintainers of your code (including yourself) to speculate as to the true nature of that variable.

Memory allocation declaring a field

How much memory Java allocates for declaring fields like private char letter; and private int size; at the moment of constucting the object containing these fields?
This depends on the implementation of the virtual machine. The spec specifies that a char primitive type has a value range of 16 Bit, but it does not specify how a virtual machine has to store an object on the heap.
There's no need for such a detailed spec, because VM's don't have to be able to exchange or serialize raw objects from the heap.
To respond to your clarification in a comment: Again, it depends on the implementation, but there a couple of good reasons to allocate the memory for all class attributes once at the time the object is "created". If we decided for lazy allocation, then we'd have to add mechanics to dynamically resize objects on the heap at runtime which is pretty expensive.
If we reserve all space right away at the beginning, then we never have to resize or relocate data on the heap, because the datastructures can never grow or shrink in size.
In the Oracle/Sun JVM, each object is allocated on an 8-byte boundary. So adding a field may not increase the amount of memory used. However as a guide here are the sizes of primitives
type typical size
byte, boolean 1 byte
char, short 2 bytes
int, float 4 bytes
long, double 8 bytes
Whether the JVM is 32-bit or 64-bit makes no differences to the size of a primitive but it does change the default size of a reference.
I don't know the specificities of the JVM,
but if that can help you the char primitive type uses 16-bit (Unicode character) to store the data, and int uses 32-bits
http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
I guess you could test it by creating a very simple Java application and a very simple object.
Run the application without declaring fields and check how much memory it uses (Ctrl+Shift+Escape in Windows), and then re-run and check the difference when you do allocate these fields.
Fields in Java classes that store primitive types are initialised with default values when the object is created, so I would imagine the memory would be allocated then.
This is implementation dependent.
Early JVM implementations were closer to the class file format. In that case byte, short, char, int, float and references take up one slot; long and double two slots. So, effectively round size up to four bytes and that's how much memory it takes up in the object. Then the total for the object, including header, is often rounded up to 8 bytes for better memory alignment. For "compressed oops" (32 bit references on 64 bit platforms, where the bottom bits of the 64-bit address are always zero, allowing the reference to be shifted and more than 4 GB used whilst keeping references down to four bytes), there is strong pressure to align to bigger sizes.
But for the best part of a decade we have had 64-bit JVMs. That means more waste, including waste in terms of processor-memory bandwidth. So in modern implementations the object layout is compacted such that object uses as much memory as you would expect (plus header and alignment rounding).

Categories

Resources