File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Performance and the fly likes System.arraycopy speed. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Performance
Bookmark "System.arraycopy speed." Watch "System.arraycopy speed." New topic
Author

System.arraycopy speed.

Alan Hollis
Greenhorn

Joined: Feb 08, 2005
Posts: 19
Just looking for clarification really that I'm doing the correct (fastest) thing.



Profiling shows this GetBytes() is taking the most amount of time in my code (obviously the functions called the most amount of times too).
However I was wondering if there's a quicker way of achieving what I'm doing above.

Apologises what might seem a silly question, but I'm new to java, and the only developer in my new job. Which means I only have you guys to discuss things with ;) (Feel free to critique the code too!!!) The code all works, I'm just unhappy with how long it takes ...

p.s CDRByteArray is always 133 bytes in size, not sure if this helps?
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12769
    
    5
System.arraycopy() is used all over the place in Java so you may be sure it is heavily optimized.
steve souza
Ranch Hand

Joined: Jun 26, 2002
Posts: 860
Is there a way you can allocate the following array once, and reuse it?

byte dest[] = new byte[Length];

I have no idea if that will help or not. A profiler should show the line or lines that are the problem.


http://www.jamonapi.com/ - a fast, free open source performance tuning api.
JavaRanch Performance FAQ
Alan Hollis
Greenhorn

Joined: Feb 08, 2005
Posts: 19
Cheers guys. I guess I'm not going to get a speed increase here.

I had noticed in another part of my code I was doing something rather silly like

string alphabet = "a";
alphabet += "b";

etc.etc.

This was slowing it down a lot.

Also, Steve, I was thinking about your suggestion. In above code I posted, would I be causing a memory leak in Java by always creating a new dest[] without implicitly destroying the old one? I understand the garbage collector will get rid of it, but when, and is it efficient in doing so in this scenario?
Alan Hollis
Greenhorn

Joined: Feb 08, 2005
Posts: 19
On another note; if anyone has time.

Is there a quick way of doing



I don't like converting to an integer and then back to a string just to get it formatted correctly. As above example
This is also quite slow. (Speed really is of the essence with this application)
I've had a quick google and I can't find a better way. Any bright sparks here think of anything?
steve souza
Ranch Hand

Joined: Jun 26, 2002
Posts: 860
As far as the array allocation I was asking can you move it out of the method and as an instance variable. That way you wouldn't have to allocate it for every method call.

As far as the code that uses the HexTime class I am not sure what you are trying to accomplish. Posting full usage of the code and a few test cases with output would be helpful. What about it seems to be slow? Not sure if it would be more efficient or not, but you could make one call to String.format(...) instead of the 3 you currently have. Is this code called a lot in a loop or something? If it is only called a few times I wouldn't expect it to be a bottleneck.
Alan Hollis
Greenhorn

Joined: Feb 08, 2005
Posts: 19
I'll definitely give your idea on moving the array instantiation out of the function.

The hex time is pretty straight forward.

I have a time HH:MM:SS which is represented in hex instead of decimal. I convert the hex string to decimal then use the string format to prepend the necessary 0s purely for formatting reasons. I'll definitely change my code not to call format string each time. This is a bit silly, don't know why I was doing it that way to be honest. Thanks for pointing that out ;)
The current code is fast, profiling shows a very small average base time for each function however I want it to be as small as it possibly can be, then I'll worry about adding more hardware to the equation.

The project is reading in binary files of varying size splitting the file into 133 byte chunks and converting them into objects before spitting the object back out as either a csv file, or into a database. My code is currently faster than what the company is currently using, but I want it to be as fast as it possibly can. Mainly for my own learning experience, but secondly because the second goal of the project is to replace reading from binary files to reading from a udp stream.

Thanks again for your replies.
steve souza
Ranch Hand

Joined: Jun 26, 2002
Posts: 860
Profile your code and see what part is the slowest and tune that first. Based on the fact that you are reading files I suspect that tuning IO will have a far greater impact on performance than anything else you are doing. If IO is the bottleneck make sure you have tried Buffered IO, or possibly the NIO packages (i haven't used them before). You can also play around with buffer size.

Also make sure you test your program in server mode. Some jvm's default to client mode. This can often make a big difference in performance. Also try to run your code with a later version jvm such as 1.6 even if you have to compile it in a lower version.

Recently I did some work where using '-server' and jdk 1.6 made my program twice as fast. No ammount of tuning would have improved my performance by a factor of 2 and this only took me a couple seconds to try.

If your hex to decimal time conversion is taking a while you could compare that to a version where you simply look up values in a Map. I am guessing your possible hours are 0-23, minutes: 0-60 and seconds 0-60. If so you could populate a map with hex string values as your key and the base 10 equivalent as the value.

Something like the following for all 60 values.




Then simply do a lookup. You would of course have to test to see if it was faster. Also, this goes against my general advice of just tuning for the sake of tuning as I suspect given the fact that the process will always involve IO (either file or network) this will probably be fast enough.



Possibly calling setLength would be worth looking into (sb.setLength(0)). I have always wondered if that would be faster than creating a new object each time. Of course you would need to profile.
R van Vliet
Ranch Hand

Joined: Nov 10, 2007
Posts: 144
Alan Hollis wrote:On another note; if anyone has time.

Is there a quick way of doing


int Hours = Integer.parseInt(HexTime.substring(0, 2),16); // 1
int Minutes = Integer.parseInt(HexTime.substring(2, 4),16); // 1
int Seconds = Integer.parseInt(HexTime.substring(4,6),16); // 1

String Time = String.format("%02d",Hours)+":"+
String.format("%02d",Minutes)+":"+
String.format("%02d",Seconds);

return Time; // 01:01:01
I don't like converting to an integer and then back to a string just to get it formatted correctly. As above example
This is also quite slow. (Speed really is of the essence with this application)
I've had a quick google and I can't find a better way. Any bright sparks here think of anything?


Well, relatively speaking, String.substring(...) is slow, String.format is slow and Integer.parseInt is slow. It can be done way way faster with some simple assumptions.

The following code is obviously less friendly on the eyes but roughly 20 times as fast on my machine :



The assumptions are :
- Code readability is secondary to performance
- HexTime is always formatted as "hhmmss" where each character is 0-9 or a-f (lowercase, if not change the convertHex method accordingly)
R van Vliet
Ranch Hand

Joined: Nov 10, 2007
Posts: 144
Also, I strongly suggest you use standard camelcase naming conventions for your variables, to the average experienced Java developer "HexTime" reads as a class name not a variable name. Best to follow language conventions.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Alan Hollis wrote:Just looking for clarification really that I'm doing the correct (fastest) thing.



Profiling shows this GetBytes() is taking the most amount of time in my code (obviously the functions called the most amount of times too).
However I was wondering if there's a quicker way of achieving what I'm doing above.

Apologises what might seem a silly question, but I'm new to java, and the only developer in my new job. Which means I only have you guys to discuss things with ;) (Feel free to critique the code too!!!) The code all works, I'm just unhappy with how long it takes ...

p.s CDRByteArray is always 133 bytes in size, not sure if this helps?



I guess there is a reason why you have bothered with a getBytes() method in the first place? It looks to me like it is just an arraycopy anyway. Looks to me like you could just replace all your calls to getBytes with just a System.arraycopy. Am I missong something here?

edit: OK I guess it's just six of one half a dozen of the other. Just a question of style I guess. probably doesn't change a whole lot.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: System.arraycopy speed.