Look at this Java code:
class PerformanceTest2{
public static void main(String args[]){
Long sum = 0L;
for(int i=0;i<Integer.MAX_VALUE;i++)
sum += i;
System.out.println("Sum = " + sum);
}
}
It is observed that it takes longer for this code since sum is 'Long' & not 'long'. So in every iteration what happens is:
sum = new Long(sum.longValue() + i); (for sum+=i;)
So, a new object is created every time. Doesn't Java support C++ like feature of returning a reference so that we could've written (possibly):
sum.longValue() += i;
possibly not having to create sum object every time around the loop? Am I right?
Well, it doesn't call the constructor. It uses:
for (int i = 0; i < Integer.MAX_VALUE; i++)
{
long tmp = sum.longValue(); // Unboxing
tmp += i;
sum = Long.valueOf(tmp); // Boxing
}
The wrapper objects are deliberately immutable - they could easily have been designed to be mutable, but immutability is often a very useful feature. If you want to write your own mutable wrapper type, you're very welcome to - at which point you could have code such as:
LongWrapper sum = new LongWrapper(0L);
for (int i = 0; i < Integer.MAX_VALUE; i++)
{
sum.add(i);
}
System.out.println("Sum = " + sum);
Or possibly:
LongWrapper sum = new LongWrapper(0L);
for (int i = 0;i < Integer.MAX_VALUE; i++)
{
sum.setValue(sum.getValue() + i);
}
System.out.println("Sum = " + sum);
I invite you to take a look at the testcases I've set up here:
http://ideone.com/Hvbs1
Your code is slow not because you are mixing long and int types, but because you are using Long instead of long. The Long type is a proper object, and immutable to boot, so every time you assign a new value to your variable, a new object is being constructed (a possible exception is if a cached object already exists for the new value). This is an expensive operation (relatively speaking).
As you will see from the example code, changing the loop to add a long instead of an int does not make it run any faster. The way to speed it up is to change the first variable to a long instead of a Long.
Java has no C++ like references. Also, the built-in wrapper classes for primitive types are deliberately made immutable. One of the reasons for this decision is, that the run-time may then cache the wrapper instances for particular values, and avoid having to create a new object (this requires, that you call valueOf instead of allocating a new object via new; the compiler does this for boxing).
So, a new object is created every time. Doesn't Java support C++ like
feature of returning a reference so that we could've written
(possibly): ...
If you use Long you are explicitly requesting wrapper type from Java. And the convention for wrapper types is: they are immutable. And immutability (as constness in C++) requires that no modifiable internals must be given to the outside. But a C++ like reference would exactly do that. (Let's skip the const reference part because that also wouldn't help you in C++.)
possibly not having to create sum object every time around the loop? Am I right?
Theoretically yes, but if you want that behaviour, why don't you use not a plain long right from the start?
Others have already explained why Long takes longer then long and how usingLong.valueOf` may be slightly faster.
Please, don't let this be a reason for not using Long. In all likelihood your overall system throughput time will not be affected by it.
If there are tight loops where this affects performance then use the primitive long there, a hand-rolled wrapper as Jon describes or MutableLong from apache commons.
Related
Let's say you have a class of object with three
integer fields that you want to possibly change, all in the same way, with one method.
Let's keep it simple and say all that the method does is add 1 to the parameter passed to it.
That is to say, the desired behavior is that by the time the method has completed, the relevant field has increased by 1.
This is impossible to achieve in Java using the primitive type "int" for those fields.
I know about how Java is "always" pass by value, and not pass by reference,
- and - i've heard whisperings on the internet that this is one reason that the Integer class exists, along with other object "wrapper" classes
for ordinarily primitive types such as int and double.
Sending an object as an argument to a method should, in theory, provide a way to [effectively, if not technically] pass by reference, since the value that is passed, is supposedly the value of the reference to the object.
Very tricky. BUT - and this is where my annoyance comes in - I've tried achieving this very simple task by passing an Integer argument instead of an
int, and the desired behavior was still not accomplished. 1 was not added to the relevant field.
And yet, when I made my very own object, which consisted of just one field, an int value, and passed an instance of this object as an argument
to an appropriate method which would simply add 1 to the passed parameter, the desired behavior was in fact accomplished. 1 was added to the relevant field.
So the questions orbiting around this query are - Is it really going to be necessary to craft my own homemade class just to carry a simple integer value
every time I want to achieve this desired behavior? Can the existing tool provided by Java, Integer, really not perform this simple task?
Instead of having one nice, neat method to handle all three of the hypothetical integer fields i mentioned in the beginning, I felt compelled (in a separate, similar project that ultimately provoked this line of thinking) to make a separate method corresponding to each of the three fields, with essentially the same exact code in each one. This seems very inefficient.
It may not seem like a big deal, on the surface, to write three similar methods instead of one, but to clarify why this dismays me - imagine instead of an object with three integer fields as I stated, there are say, i don't know, four thousand. It would be so much better to write just one thing to perform the same kind of behavior, instead of copying and pasting (and changing whatever little bits necessary) four thousand times.
So I suppose the ultimate question is,
Why doesn't Integer function in a reasonable way? What's the point of wrapping a primitive in an Object at all, if it doesn't even help perform something this simple? Am I missing something simple about how to get Integer to function in the desired way? (Hopefully so) The answer seems close yet infuriatingly out of reach since "RInteger" produces the desired behavior, yet "Integer" doesn't.
The entire source code I used while trying to figure out how to construct this painstaking question is below.
package r9mp;
import javax.swing.SwingUtilities;
public class RefTest2 {
//[main m]
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new RefTest2();
}
});
}
//[fields]
int i;
Integer I;
RInteger RI;
//[constr]
public RefTest2(){
intTest();
IntegerTest();
RIntegerTest();
display();
}
//[methods]
private void intTest(){
i = 100;
intMethod(i);
}
private void IntegerTest(){
I = 100; //boxing? auto?
IntegerMethod(I);
I = 100; //just in case.
IntegerMethod2(I);
}
private void RIntegerTest(){
RI = new RInteger(100);
RIntegerMethod(RI);
}
private void intMethod(int ipar){
ipar = ipar + 1;//no change. expected.
}
private void IntegerMethod(Integer IPar){
IPar = IPar + 1;//no change. frustrating.
pln("From inside IntegerMethod: IPar = " + IPar );
pln("From inside IntegerMethod: I = " + I );
}
private void IntegerMethod2(Integer IPar){
IPar = new Integer(IPar+1);//still no change. there are no set methods for Integer, or I'd try them.
}
private void RIntegerMethod(RInteger riPar){
riPar.value = riPar.value + 1;
}
private void display(){
pln(
"Display... \n" +
"i: " + i + "\n" +
"I: " + I + "\n" +
"RI: " + RI + "\n" +
"--------"
);
}
private void pln(){
pln("");
}
private void pln(String s){
System.out.println(s);
}
//[internal class]
private class RInteger{
int value;
public RInteger(int v){
value = v;
}
public String toString(){
return ""+value;
}
}
}
And, here is the output...
How about one method for primitives and their wrappers?
private int incInteger(int value)
{
return value + 1;
}
and call for it:
int intVal = 100;
intVal = incInteger(intVal);
Integer integerVal = 200;
integerVal = incInteger(integerVal);
First of all, you need to read up on immutability to find out why it is a very good thing to have. There even exist entire languages (functional, mostly) that capitalize on it.
Once you have read about that, then read Eric Lippert's series of articles on immutability. Start here: https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/ Mind = blown.
But to give you a quick hint as to why primitive wrappers like Integer are immutable, let me just say that these classes are often used as keys in Hash Maps, and a key must be immutable, so that its hashCode will never change, otherwise the hash map will fail with very difficult to track down behaviour. Mutable keys in hashmaps are nasty bugs.
You can achieve what you want with a class of your own devise which plays the role of a reference, or by simply passing an array and modifying the element at array[0].
My personal preferences are as follows:
I would try to do as much as possible with return values.
When return values are inapplicable, (as the case is with invokeLater,) then inner/nested/anonymous classes that have access to the fields of the enclosing class are my next preference.
When that's not an option either, then special classes crafted precisely for the application at hand are my next option. (MyMutableNumberWrapper.)
And when I just want something quick and dirty, then general-purpose classes like Ref<T> (or even single-element arrays) would be my final option.
I am facing a confusion while working with objects. I searched google but couldn't find actual words to search for. The question is:
I am working with objects which consist some other object. For example:
public void mapObjects(A a, B b) {
a.setWeight(BigDecimal.valueOf(b.getWeight));
//Now my doubt lies here
if (a.getCharges.getDiscounts.getDiscountList != null) {
for(int i = 0; i < a.getCharges.getDiscounts.getDiscountList.size(); i++){
b.getList().get(0).setDiscountValue(a.getCharges.getDiscounts.getDiscountList.get(i).getValue());
b.getList().get(0).setDiscountName(a.getCharges.getDiscounts.getDiscountList.get(i).getValue);
}
}
}
The above code is just an example. The project in which I am working uses similar type of coding style. The usage of a.getCharges.getDiscounts.getDiscountList() kind of code always bugs me. Because I am again and again calling the same statement.
When I asked a senior why dont we save this statement into a simple List<> variable. He told me that it will use extra references which will increase overhead. Can using a variable be that much overhead than calling getters again and again?
As Java exchanges references not actual object, if you take a local variable it will just add a reference variable entry in stack frame.
This memory would be very less, almost negligible
This memory will be released once the method is completed because this will be local to the method
Despite that, you can gain significant performance gains if you use local variables. You are extracting same information within loop multiple times.
a.getCharges.getDiscounts.getDiscountList.size() is called multiple times. It should be a local variable.
b.getList().get(0) is being called multiple times. It should be a local variable.
a.getCharges.getDiscounts.getDiscountList is called multiple times. It should be a local variable.
Changing these to local variables would results in good performance gains, because unnecessary method calls would be saved.
Point your senior to this. If it works for limited resources on Android, I guess the technique of storing in local variables everything used in a for cycle is actually beneficial for performance anywhere.
In the excerpt below, note that we aren't even speaking about the overhead introduced by calling the (virtual) list.size() method, only storing the array.length as a local variable produces notable differences in performance.
public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}
public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the loop.
one() is faster. It pulls everything out into local variables, avoiding the lookups. Only the array length offers a performance benefit.
two() is fastest for devices without a JIT, and indistinguishable from one() for devices with a JIT. It uses the enhanced for loop syntax introduced in version 1.5 of the Java programming language.
Just make the discountList field never null - ie initialized to an empty list - and iterate over it. Something like:
for (Discount discount : a.getCharges().getDiscounts().getDiscountList()) {
b.getList().get(0).setDiscountValue(discount.getValue());
b.getList().get(0).setDiscountName(discount.getName());
}
Your "senior" may need to do some research. The "performance impact" of doing this is a few bytes per object and a few microseconds per access. If he's really hung up about memory, initialise it with a LinkedList, which has almost no memory footprint.
In Java a variable V pointing to an object instance O is simply a numeric value pointing to a memory location where the object's data is stored.
When we assign Vto another variable V1 all that happens is that V1 now points to the same memory location where data for O is stored. This means that new memory is not allocated when you do simple assignment unlike C++ code where the = operator can be be overloaded to do a deep-copy in which case new memory is actually allocated. Illustrating with an example below
Consider a class like below
class Foo {
private List<String> barList = new ArrayList<>();
//class methods...
//getter for the list
List<String> getBarList() {
return this.barList;
}
}
public static void main(String[] args) {
Foo f = new Foo()
//the below lien will print 0 since there is no bar string added
System.out.println("Bar list size: " + f.getBarList().size());
// add a bar string. Observe here that I am simply getting the list
// and adding - similar to how your code is currently structured
f.getBarList().add("SomeString");
//now get a reference to the list and store it in a variable.
// Below anotherList only points to the same memory location
// where the original bar list is present. No new memory is allocated.
List<String> anotherList = f.getBarList();
//print the content of bar list and another list. Both will be same
for(String s : f.getBarList()) {
System.out.println(s);
}
for(String s: anotherList) {
System.out.println(s);
}
//add a new bar string using the reference variable
anotherList.add("Another string");
//print the content of bar list and another list. Both will be same. If anotherList had separate memory allocated to it then the new string added would be only seen when we print the content of anotherList and not when we print the content of f.getBarList(). This proves that references are only some numeric addresses that point to locations of the object on heap.
for(String s : f.getBarList()) {
System.out.println(s);
}
for(String s: anotherList) {
System.out.println(s);
}
}
Hope this helps.
I have a couple of questions:
Regarding the creation of References to Objects and primitive
values, I was wondering: when is it usually appropriate to store
values in a variable?
From my general knowledge, the rule of thumb would be to create
references when the same value is used more than once or to avoid
hard-coding E.g.
String name = "Bob";
System.out.println("Welcome " + name + ". Is your name really " + name + "?");
Whereas if it is only used once like in the example below, it would
be more performant to simply do the following.
System.out.println("Welcome Bob");
as opposed to
String name = "Bob";
System.out.println("Welcome " + name + ".");
Added question: If we are talking about a variable that is used when iterating over an array or enumerable object, which of the following would be more performant (assuming we are looping over an object like 1 million times)? Or would there be no difference and is simply a stylistic choice?
For example,
// nameArray is an extremely long array
public static void loop(String[] nameArray) {
String name; //Should this be declared inside the loop?
int len = nameArray.length();
for(int i = 0; i < len; i++) {
name = nameArray[i];
System.out.println(name);
}
}
or would this be more preferred?
// nameArray is an extremely long array
public static void loop(String[] nameArray) {
int len = nameArray.length();
for(int i = 0; i < len; i++) {
String name = nameArray[i]; //Declare String reference inside for loop
System.out.println(name);
}
}
In regards to garbage collection, after a reference to an object/primitive
has passed its useful life, is it always good practice to set
that value to null to make it eligible for garbage collection (assuming that there are no other references to that object/primitive value) ?
For example,
String name = "Bob";
System.out.println("Welcome " + name + ".);
name = null;
thank you in advance for taking time to look at this.
No it makes no difference - the object is allocated whether you use a local variable to refer to it or not. Use whatever is more readable.
It is almost never good practice to set values to null explicitly. There are a few corner cases, such as when not doing it would hold unnecessary references to variables that would otherwise be eligible for garbage collection (see for example: Effective Java - Item 6: Eliminate obsolete object references). In all other situations, limiting the scope of variables as much as possible is the most efficient way to help the garbage collector.
The bottom line being: use variables when you need them and let the garbage collector do its job, unless you have a compelling reason not to.
when is it usually appropriate to store values in a variable?
In most cases the answer is: When the code benefits from it from a maintenance perspective. If the code becomes easier to understand or debug, then use a variable.
After a reference to an object/primitive has passed its useful life, is it always good practice to set that value to null to make it eligible for garbage collection?
If the variable goes out of scope shortly after, then setting it to null will just unnecessarily clutter the code. I would use it only for long-lived variables, and perhaps for variables that point to large objects.
From my general knowledge, the rule of thumb would be to create references when the same value is used more than once or to avoid hard-coding
Please, forget this rule. Use variables and their scope to help others (and you) understand your program more easily. You can do something like this
private static final String MY_UNCLE_NAME = "Bob";
System.out.println(String.format("Welcome %s.", MY_UNCLE_NAME));
Updated
If we are talking about a variable that is used when iterating over an array or enumerable object, which of the following would be more performant (assuming we are looping over an object like 1 million times)? Or would there be no difference and is simply a stylistic choice?
Always use this (keep a scope of variables as less as possible and forget about local optimizations).
// nameArray is an extremely long array
public static void loop(String[] nameArray) {
int len = nameArray.length();
for(int i = 0; i < len; i++) {
String name = nameArray[i]; //Declare String reference inside for loop
System.out.println(name);
}
}
In one of my Java projects I am plagued by code repetition due to the way Java handles (not) primitives. After having to manually copy the same change to four different locations (int, long, float, double) again, for the third time, again and again I came really close (?) to snapping.
In various forms, this issue has been brought up now and then on StackOverflow:
Managing highly repetitive code and documentation in Java
How to avoid repetition when working with primitive types?
Passing dynamic list of primitives to a Java method
The consensus seemed to converge to two possible alternatives:
Use some sort of code generator.
What can you do? C'est la vie!
Well, the second solution is what I am doing now and it is slowly becoming dangerous for my sanity, much like the well known torture technique.
Two years have passed since these questions were asked and Java 7 came along. I am, therefore, hopeful for an easier and/or more standard solution.
Does Java 7 have any changes that might ease the strain in such cases? I could not find anything in the condensed change summaries, but perhaps there is some obscure new feature somewhere?
While source code generation is an alternative, I'd prefer a solution supported using the standard JDK feature set. Sure, using cpp or another code generator would work, but it adds more dependencies and requires changes to the build system.
The only code generation system of sorts that seems to be supported by the JDK is via the annotations mechanism. I envision a processor that would expand source code like this:
#Primitives({ "int", "long", "float", "double" })
#PrimitiveVariable
int max(#PrimitiveVariable int a, #PrimitiveVariable int b) {
return (a > b)?a:b;
}
The ideal output file would contain the four requested variations of this method, preferrably with associated Javadoc comments e.t.c. Is there somewhere an annotation processor to handle this case? If not, what would it take to build one?
Perhaps some other trick that has popped up recently?
EDIT:
An important note: I would not be using primitive types unless I had a reason. Even now there is a very real performance and memory impact by the use of boxed types in some applications.
EDIT 2:
Using max() as an example allows the use of the compareTo() method that is available in all numeric boxed types. This is a bit trickier:
int sum(int a, int b) {
return a + b;
}
How could one go about supporting this method for all numeric boxed types without actually writing it six or seven times?
I tend to use a "super type" like long or double if I still want a primitive. The performance is usually very close and it avoids creating lots of variations. BTW: registers in a 64-bit JVM will all be 64-bit anyway.
Why are you hung up on primitives? The wrappers are extremely lightweight and auto-boxing and generics does the rest:
public static <T extends Number & Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
This all compiles and runs correctly:
public static void main(String[] args) {
int i = max(1, 3);
long l = max(6,7);
float f = max(5f, 4f);
double d = max(2d, 4d);
byte b = max((byte)1, (byte)2);
short s = max((short)1, (short)2);
}
Edited
OP has asked about a generic, auto-boxed solution for sum(), and will here it is.
public static <T extends Number> T sum(T... numbers) throws Exception {
double total = 0;
for (Number number : numbers) {
total += number.doubleValue();
}
if (numbers[0] instanceof Float || numbers[0] instanceof Double) {
return (T) numbers[0].getClass().getConstructor(String.class).newInstance(total + "");
}
return (T) numbers[0].getClass().getConstructor(String.class).newInstance((total + "").split("\\.")[0]);
}
It's a little lame, but not as lame as doing a large series of instanceof and delegating to a fully typed method. The instanceof is required because while all Numbers have a String constructor, Numbers other than Float and Double can only parse a whole number (no decimal point); although the total will be a whole number, we must remove the decimal point from the Double.toString() before sending it into the constructor for these other types.
Does Java 7 have any changes that might ease the strain in such cases?
No.
Is there somewhere an annotation processor to handle this case?
Not that I am aware of.
If not, what would it take to build one?
Time, or money. :-)
This seems to me like a problem-space where it would be difficult to come up with a general solution that works well ... beyond trivial cases. Conventional source code generation or a (textual) preprocessor seems more promising to me. (I'm not an Annotation processor expert though.)
If the extraordinary verbosity of Java is getting to you, look into some of the new, higher-level languages which run on the JVM and can interoperate with Java, like Clojure, JRuby, Scala, and so on. Your out-of-control primitive repetition will become a non-issue. But the benefits will go much further than that -- there are all kinds of ways which the languages just mentioned allow you to get more done with less detailed, repetitive, error-prone code (as compared to Java).
If performance is a problem, you can drop back into Java for the performance-critical bits (using primitive types). But you might be surprised at how often you can still get a good level of performance in the higher-level language.
I personally use both JRuby and Clojure; if you are coming from a Java/C/C#/C++ background, both have the potential to change the way you think about programming.
Heh. Why not get sneaky? With reflection, you can pull the annotations for a method (annotations similar to the example you've posted). You can then use reflection to get the member names, and put in the appropriate types... In a system.out.println statement.
You would run this once, or each time you modded the class. The output could then be copy-pasted in. This would probably save you significant time, and not be too hard to develop.
Hm ,as for the contents of the methods... I mean, if all your methods are trivial, you could hard code the style (ie if methodName.equals("max") print return a>b:a:b etc. Where methodName is determined via reflection), or you could, ummmmm... Hm. I'm imagining the contents can be easily copy pasted, but that just seems more work.
Oh! Whty not make another annotation called " contents ", give it a string value of the method contents, add that to the member, and now you can print out the contents too.
In the very least, the time spent coding up this helper, even if about as long as doing the tedious work, well, it would be more interesting, riiiight?
Your question is pretty elaborate as you already seem to know all the 'good' answers. Since due to language design we are not allowed to use primitives as generic parameter types, the best practical answer is where #PeterLawrey is heading.
public class PrimitiveGenerics {
public static double genericMax( double a, double b) {
return (a > b) ?a:b;
}
public int max( int a, int b) {
return (int) genericMax(a, b);
}
public long max( long a, long b) {
return (long) genericMax(a, b);
}
public float max( float a, float b) {
return (float) genericMax(a, b);
}
public double max( double a, double b) {
return (double) genericMax(a, b);
}
}
The list of primitive types is small and hopefully constant in future evolution of the language and double type is the widest/most general.
In the worst case, you compute using 64 bit variables where 32 bit would suffice. There is a performance penalty for conversion(tiny) and for pass by value into one more method (small), but no Objects are created as this is the main (and really huge) penalty for using primitive wrappers.
I also used a static method so it is bound early and not in run-time, although it is just one and which is something that JVM optimization usually takes care of but it won't hurt anyway. May depend on real case scenario.
Would be lovely if someone tested it, but I believe this is the best solution.
UPDATE:
Based on #thkala's comment, double may only represent long-s until certain magnitude as it loses precision (becomes imprecise when dealing with long-s) after that:
public class Asdf2 {
public static void main(String[] args) {
System.out.println(Double.MAX_VALUE); //1.7976931348623157E308
System.out.println( Long.MAX_VALUE); //9223372036854775807
System.out.println((double) Long.MAX_VALUE); //9.223372036854776E18
}
}
From the performance point of view (I make a lot of CPU-bound algorithms too), I use my own boxings that are not immutable. This allows using mutable numbers in sets like ArrayList and HashMap to work with high performance.
It takes one long preparation step to make all the primitive containers with their repetitive code, and then you just use them. As I also deal with 2-dimensional, 3-dimensional etc values, I also created those for myself. The choice is yours.
like:
Vector1i - 1 integer, replaces Integer
Vector2i - 2 integer, replaces Point and Dimension
Vector2d - 2 doubles, replaces Point2D.Double
Vector4i - 4 integers, could replace Rectangle
Vector2f - 2-dimensional float vector
Vector3f - 3-dimensional float vector
...etc...
All of them represent a generalized 'vector' in mathematics, hence the name for all these primitives.
One downside is that you cannot do a+b, you have make methods like a.add(b), and for a=a+b I chose to name the methods like a.addSelf(b). If this bothers you, take a look at Ceylon, which I discovered very recently. It's a layer on top of Java (JVM/Eclispe compatbile) created especially to address it's limitations (like operator overloading).
One other thing, watch out when using these classes as a key in a Map, as sorting/hashing/comparing will go haywire when the value changes.
I'd agree with previous answers/comments that say there isn't a way to do exactly what you want "using the standard JDK feature set." Thus, you are going to have to do some code generation, although it won't necessarily require changes to the build system. Since you ask:
... If not, what would it take to build one?
... For a simple case, not too much, I think. Suppose I put my primitive operations in a util class:
public class NumberUtils {
// #PrimitiveMethodsStart
/** Find maximum of int inputs */
public static int max(int a, int b) {
return (a > b) ? a : b;
}
/** Sum the int inputs */
public static int sum(int a, int b) {
return a + b;
}
// #PrimitiveMethodsEnd
// #GeneratedPrimitiveMethodsStart - Do not edit below
// #GeneratedPrimitiveMethodsEnd
}
Then I can write a simple processor in less than 30 lines as follows:
public class PrimitiveMethodProcessor {
private static final String PRIMITIVE_METHODS_START = "#PrimitiveMethodsStart";
private static final String PRIMITIVE_METHODS_END = "#PrimitiveMethodsEnd";
private static final String GENERATED_PRIMITIVE_METHODS_START = "#GeneratedPrimitiveMethodsStart";
private static final String GENERATED_PRIMITIVE_METHODS_END = "#GeneratedPrimitiveMethodsEnd";
public static void main(String[] args) throws Exception {
String fileName = args[0];
BufferedReader inputStream = new BufferedReader(new FileReader(fileName));
PrintWriter outputStream = null;
StringBuilder outputContents = new StringBuilder();
StringBuilder methodsToCopy = new StringBuilder();
boolean inPrimitiveMethodsSection = false;
boolean inGeneratedPrimitiveMethodsSection = false;
try {
for (String line;(line = inputStream.readLine()) != null;) {
if(line.contains(PRIMITIVE_METHODS_END)) inPrimitiveMethodsSection = false;
if(inPrimitiveMethodsSection)methodsToCopy.append(line).append('\n');
if(line.contains(PRIMITIVE_METHODS_START)) inPrimitiveMethodsSection = true;
if(line.contains(GENERATED_PRIMITIVE_METHODS_END)) inGeneratedPrimitiveMethodsSection = false;
if(!inGeneratedPrimitiveMethodsSection)outputContents.append(line).append('\n');
if(line.contains(GENERATED_PRIMITIVE_METHODS_START)) {
inGeneratedPrimitiveMethodsSection = true;
String methods = methodsToCopy.toString();
for (String primative : new String[]{"long", "float", "double"}) {
outputContents.append(methods.replaceAll("int\\s", primative + " ")).append('\n');
}
}
}
outputStream = new PrintWriter(new FileWriter(fileName));
outputStream.print(outputContents.toString());
} finally {
inputStream.close();
if(outputStream!= null) outputStream.close();
}
}
}
This will fill the #GeneratedPrimitiveMethods section with long, float and double versions of the methods in the #PrimitiveMethods section.
// #GeneratedPrimitiveMethodsStart - Do not edit below
/** Find maximum of long inputs */
public static long max(long a, long b) {
return (a > b) ? a : b;
}
...
This is an intentionally a simple example, and I'm sure it doesn't cover all cases, but you get the point and can see how it could be extended e.g. to search multiple files or use normal annotations and detect method ends.
Furthermore, whilst you could set this up as a step in your build system, I set this up to run as a builder before the Java builder in my eclipse project. Now whenever I edit the file and hit save; it's updated automatically, in place, in less than a quarter of a second. Thus, this becomes more of a editing tool, than a step in the build system.
Just a thought...
There's a general advice to use Integer.valueOf(int) instead of new Integer(int) because of caching.
In JDK 5+, you should really use valueOf because Integer now caches Integer objects between -128 and 127 and can hand you back the same exact Integer(0) object every time instead of wasting an object construction on a brand new identical Integer object.
How can extend the range?
You can use the java.lang.Integer.IntegerCache.high property to increase the size of this cache.
ex :
java -Djava.lang.Integer.IntegerCache.high=4096 SomeClass.class
My questions to you are:
1) Why is your code making new Integer objects hurting you? Do you have a profile result to share, to prove that making too many Integers is slowing your down? Object pooling, in general, is a BAD idea. You need a good case to justify it.
2) Why are you doing new Integer(int)? If you just keep it as a primitive int, not only will you avoid "creating a new object". you will not create any object at all. Auto boxing will handle converting it to an Integer if you need it at a later point in time.
*Disclaimer I Don't use EITHER.. I write performance sensitive code, but have never come to a point where I would manually turn a primitive int into an Integer. I just keep as an int whenever possible, and let the JVM autobox if it is needed.
Apparently, the -XX:+AggressiveOpts sets the max to 20000. See the answer on How large is the Integer cache?
Extending the range of the cache may not get you what you are wanting, but if you have a real need to cache a greater range, you can use this code instead of Integer.valueOf(int). You just need to adjust the cache range values to the range you want.
private static class IntegerCache
{
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static
{
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
public static Integer valueOf(int i)
{
final int offset = 128;
if (i >= -128 && i <= 127) // must cache
{
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
The code is from: http://www.owasp.org/index.php/Java_gotchas
This is why the integer cache was added:
[...] to support the object identity semantics of autoboxing for values between -128 and 127 (inclusive), as required by the language specification.
If you profiled your app and you noticed that creating Integer objects is a hotspot, then by all means, copy the integer cache code and write your own with a different range. Otherwise your time would be better spent finding the real hotspots and improving those.