Consider the following two code snippets:
System.out.print(i + " ");
or
System.out.print(i);
System.out.print(" ");
Although both will end up printing the same output, which variant will be faster, in terms of execution speed?
For some context, the reason I am asking is that converting the first one to the second one resulted in a "time limit exceeded (TLE)" error in my online compiler. That suggests that the first one is faster, but I don't know if that is universally true. I would also like to understand why.
You can't really know - it depends on factors not evident in your code.
i + " "
slower?For that to be slower, i
needs to be a very large string (or some object whose toString()
method returns a very large string, thus resulting in the i + " "
operation being relatively pricey. It's still an entirely in-memory affair, so compared to most I/O, it's negligible, but make that a string of a million characters or so and that is likely going to result in this being slower.
i
, then " "
slower?System.in
is, or isn't, buffered. You get no guarantees. It's usually a sizable chain of systems tied together, and eventually, you end up writing to a file (if you ran java -cp . yourpkg.YourClass >output.txt
for example), or a console, and if that console is running over ssh, TCP/IP packets over a network, etcetera.
Many of these systems add tons of overhead because these are so-called 'packeting' systems: They can't send or process single bytes at all. They can only process in sizable chunks. Take networking: To send some data from one computer on the internet to another, you wrap the data you want to send in a so-called packet, which includes many bytes of data which is used for systems that process that data to know what to do with it. This data will travel through your network card, your router, the tiny little closet thingie at the end of the street, the larger network hub in your town, to a major distribution trunk, across the fiber to the other side of the ocean, and then allll that, back to a server you've ssh
-ed into. Should be obvious that you need quite a few bytes of info to make this happen.
So, if you want to send just Hello
and nothing more, then an entire packet is made. It could have carried maybe 1800 bytes of data, but it will carry only 5. it still has the ~100 bytes of overhead for the routing info though. So, the Hello packet is in grand total about 105 bytes large. Your network card shunts that off to your router and it's off to the wide world and then your code almost immediately says: Okay, great, now send a space! - and this results in your system dutifully crafting another packet, applying all that routing overhead, and off goes a 101-byte packet, for a grand total of 2 separate packets, totalling 206 bytes.
Contrast to sending Hello
in one shot, for a single packet of 106 bytes.
That's an example of why usually 'buffering', or failing that, bunching your sends into fewer actual writes, will be faster. But the problem is, you have no idea where System.out
goes. Console? Network? File? bitbucket? Who knows. If you run java -jar yourapp.jar >/dev/null
, System.out
is incredibly fast (as the data goes absolutely nowhere). Your question doesn't mention where this goes.
NB: Files end up being packet-based too, modern SSDs can't write single bytes to disk, only entire chunks in one go. If you first write 'hello', the SSD ends up reading an entire chunk into memory, then updating some bytes so they read 'hello', then flashing the location on disk with a surge of power that resets that entire segment, and then writing the whole chunk of many thousands of bytes large back. If you then write a space, that whole routine is done a second time, whereas if you call write only once, the disk will likely do this 'load an entire chunk, update data, surge the chunk, save the chunk' song and dance routine only once.
Well, no. That's the point. However, usually, it doesn't matter and they are equally fast. But, if it matters, it is highly likely that i + " "
will be faster.