Difference between revisions of "Talk:Code Size"

From Robowiki
Jump to navigation Jump to search
m
m (Using <syntaxhighlight>.)
 
(29 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 +
= Migrated Discussion =
 +
Migrated discussion page: [[CodeSize/Old discussion]]
 +
 +
= New Discussion =
 
Codesize for some reason doesn't work for me.  Can someone make a GUI version of it?  It isn't too hard with Swing. (I've made a compression program with an algorithm of my own invention with a Swing GUI.)  Or could someone post a javascript that detects it (the size) after you paste code in?
 
Codesize for some reason doesn't work for me.  Can someone make a GUI version of it?  It isn't too hard with Swing. (I've made a compression program with an algorithm of my own invention with a Swing GUI.)  Or could someone post a javascript that detects it (the size) after you paste code in?
 
Thanks!  --[[User:Awesomeness|Awesomeness]] 21:05, 13 March 2009 (UTC)
 
Thanks!  --[[User:Awesomeness|Awesomeness]] 21:05, 13 March 2009 (UTC)
 +
 +
All you need to do to run the code size utility is "java -jar /path/to/it/codesize.jar /path/to/my/class.class". If you still can't get that working or just find it easier, you can use the "Package robot for upload" feature of Robocode which will tell you what the codesize is. Note, it's impossible for a javascript to easily detect the codesize of pastes java source code, because it's measured from the compiled bytecode not the source. --[[User:Rednaxela|Rednaxela]] 21:16, 13 March 2009 (UTC)
 +
 +
== Reducing Code Size ==
 +
 +
Well, I have a strong nano but it's roughly 280 in code size.  I know I can shrink it...  I'm just not very good at it.  This method takes like twenty codesize points, (that's what I'll call them) and I SERIOUSLY need to shrink it.  Any help please?
 +
 +
Code:
 +
<syntaxhighlight>
 +
public void alternate() {
 +
i();
 +
if (alternate) {
 +
alternate = false;
 +
i();
 +
return;
 +
}
 +
alternate = true;
 +
}
 +
</syntaxhighlight>
 +
At least I TRIED to shrink it!
 +
 +
 +
lolz,
 +
:--[[User:Awesomeness|Awesomeness]] 01:22, 18 March 2009 (UTC)
 +
 +
The following is probably smaller codesize, but I haven't tested:
 +
<syntaxhighlight>
 +
public void alternate() {
 +
i();
 +
alternate = !alternate;
 +
if (!alternate) {
 +
i();
 +
}
 +
}
 +
</syntaxhighlight>
 +
I'm not sure what i() does but I wonder if running it twice is REALLY a necessity, or if it could be worked around with very little codesize cost. Also, if codesize is critical, as it usually is for nanos, I'd suggest trying to reduce the number of number of methods in your code. If you have any methods in your code that are only called once, stop making it a seperate method. Some other tips are [http://robowiki.net/cgi-bin/robowiki?CodeSize/WritingSmallCode here] in case you haven't see that. It would be easier to help if we could see more of the code, though I do have the suspicion that the biggest thing causing large codesize right now is that you may have too many methods. --[[User:Rednaxela|Rednaxela]] 02:04, 18 March 2009 (UTC)
 +
 +
This may be even smaller
 +
<syntaxhighlight>
 +
public void alternate() {
 +
i();
 +
if (!(alternate = !alternate)) {
 +
i();
 +
}--~~~~
 +
}
 +
</syntaxhighlight>
 +
--[[User:Zyx|zyx]] 06:36, 18 March 2009 (UTC)
 +
 +
* Maybe, but I thought I tested that type of modification to not actually be helpful despite it's common usage in nanos. Doesn't hurt to test that though, I may be wrong. --[[User:Rednaxela|Rednaxela]] 07:00, 18 March 2009 (UTC)
 +
* I have found that this type of modifications can help, but only sometimes. I think, that how many times(or some other factors) you use the same variable again affect how the compiler translates them or something like that. But my final conclusion on codesize is that everything has to be tested, because it is really hard to know before hand how it will affect codesize. --[[User:Zyx|zyx]] 07:22, 18 March 2009 (UTC)
 +
** What affects it is if you have to switch between variables. Here, the boolean <code>alternate</code> is being accessed 3 times in a row, so inlining it wouldn't help. However, if you called <code>i()</code> in between changing it and accessing it for the <code>if</code> then inlining would help because <code>alternate</code> does not have to be re-loaded into the registers. So what really matters is execution order, not whether it is inlined. Sometimes, however, it only possible to get the execution order correct by inlining. By 'correct' I mean switching between different variables as little as possible. --[[User:Skilgannon|Skilgannon]] 11:15, 18 March 2009 (UTC)
 +
* Hm, this tempts me to try coding a nanobot using [http://en.wikipedia.org/wiki/Jasmin_(Java_assembler) a java assembler] in order to see if I can make any smaller codesize bytecode than the normal compiler would... --[[User:Rednaxela|Rednaxela]] 07:35, 18 March 2009 (UTC)
 +
* If you really want to go that deep I recommend this [http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html book], it is the official JavaTM Virtual Machine Specification. It fully explains how a class file is encoded, there are many weird stuff in that VM. I haven't used that for codesize at all, I used it for a homework once. --[[User:Zyx|zyx]] 07:52, 18 March 2009 (UTC)
 +
* As for coding java assembler ... maybe not yet for me. But looking at assembler to try to shrink is a definite yes for me. You also learn a lot of bytecode stuff from that, some of which can be guessed. (http://andrei.gmxhome.de/bytecode/index.html is super useful, it's a plugin in Eclipse that lets you view bytecode with the source) --[[User:Starrynte|Starrynte]] 00:51, 5 May 2009 (UTC)
 +
 +
 +
Thank you!  I've been making a nano.  Yeah, two I()s are needed.  I'll try these out!
 +
 +
Hi! There is a static final double constant that I want to be equal to 0.2. I realised, that if I write 1/5 instead of 0.2, I gain 2 bytes. But for some reason, that value of the constant will be 0.0! Do you have any idea? --[[User:Robar|HUNRobar]] 19:48, 28 March 2009 (UTC)
 +
 +
At last I figured it out. 1 and 5 are integers and for some myterious reason it calculated the value also as an integer: 0. As soon as I replaced it with 1.0/5.0, the 2 bytes came back and the constant was given the value. --[[User:Robar|HUNRobar]] 20:01, 28 March 2009 (UTC)
 +
 +
Well, wouldn't call it mysterious. All programming languages I've heard of keep integer input operators as having an integer output. One note is that 1.0/5 or 1/5.0 would also give 0.2 (no different codesize though, because the compiler optimizes 1.0/5.0 to a 0.2 in the bytecode I believe). Of course if one wants otherwise.... maybe one should design processors that have a native number format off "one sum of primes divided by another sum of primes" instead of binary integers and [http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE 754]? :D --[[User:Rednaxela|Rednaxela]] 20:14, 28 March 2009 (UTC)
 +
:* Just as a footnote, in most low-level languages a/b is integer division if both a and b are integers. Integer division is a very important operation, is much faster than floating point division and you can easily tell the compiler you want floating point division (<code>(double)a/b</code>). Languages that perform division as floating point always are forced to offer a function to force an integer division, many times implemented as (<code>c = a/b; return c < 0 ? ceil(c) : floor(c)</code>) which is extremely slow, specially considering processors have a hardwired integer division operation. But I know is one of the darkest bugs one can have, a good exercise is to always check when you are going to divide if it is an integer division or not what you want. --[[User:Zyx|zyx]] 00:23, 29 March 2009 (UTC)
 +
 +
I'm going mad, because I squeezed my nano from 263 bytes to 251, and I've stuck with the last two for an hour! --[[User:Robar|HUNRobar]] 20:59, 28 March 2009 (UTC)
 +
 +
Haha, I've sometimes had times like that, though I don't do codesize restricted bots much. If you update/post your bot's code on it's page and mention which one it is, people might have codesize suggestions to offer. :) --[[User:Rednaxela|Rednaxela]] 21:21, 28 March 2009 (UTC)
 +
 +
 +
--
 +
Ok, I've found a new issue.  I have a bot that my local codesize utility is reporting at 249, but the robocode built in version is showing 336.  I'm wondering if I'm missing something.  I'll go double check and make sure I have the latest codesize.jar in my test batch file. --[[User:Miked0801|Miked0801]] 00:35, 13 May 2009 (UTC)
 +
 +
Never mind - I had multiple classes... --[[User:Miked0801|Miked0801]] 03:09, 13 May 2009 (UTC)
 +
 +
I just discovered that setting my number of bins to 255 in Toorkild saves me 2 bytes over the old 230 I had before. Odd... --[[User:Skilgannon|Skilgannon]] 10:26, 5 November 2009 (UTC)
 +
 +
Perhaps loading 255 (1111 1111) costs a little less than 230 (1110 0110)? Or you have reduced somewhere and you haven't noticed? --[[User:Nat|<span style="color:#099;">Nat</span>]] [[User talk:Nat|<span style="color:#0a5;">Pavasant</span>]] 12:58, 5 November 2009 (UTC)
 +
 +
If the bins number is an integer, then probably you reduced somewhere else (since from my tests they are both the same, since they both use SIPUSH). The only other possibility I can think of is that jikes somehow compiled 230 with SIPUSH, and 255 with LDC. For whatever reason, codesize thinks LDC is smaller than SIPUSH, though the bytecode reference says SIPUSH is smaller. --[[User:Starrynte|Starrynte]] 03:25, 6 November 2009 (UTC)
 +
 +
I went through it very carefully, that was the only change I made. And it's only 255. 256 comes out with an extra 2 bytes, as does 254. It's using less bytes than it would to load 0. I can't see any other code that would simplify for 255. The only way I can get a lower codesize is by using 1, and that's because two doubles simplify to 0 later on , ie. ((BINS-1)/(2*Math.PI)) = 0 when BINS = 1. If you want to experiment [http://www.minifly.rchomepage.com/robocode/jk.micro.Toorkild_0.2.2.jar Toorkild 0.2.2] is the bot I noticed it in. --[[User:Skilgannon|Skilgannon]] 12:13, 6 November 2009 (UTC)
 +
 +
== ASM (byte code manipulation) ==
 +
 +
This library for direct manipulation of Java byte code looks interesting: [http://asm.ow2.org/ OW2: ASM]. (I know people have mentioned this kind of thing re: Mini/Micro/NanoBots before, but I don't know what other tools are out there, so just thought I'd share.) --[[User:Voidious|Voidious]] 15:34, 24 May 2010 (UTC)
 +
 +
I believe there is [http://jasmin.sourceforge.net/ Jusmin Java Assembler]. Look like they serve the same purpose, though. --[[User:Nat|<span style="color:#099;">Nat</span>]] [[User talk:Nat|<span style="color:#0a5;">Pavasant</span>]] 07:36, 25 May 2010 (UTC)

Latest revision as of 09:33, 1 July 2010

Migrated Discussion

Migrated discussion page: CodeSize/Old discussion

New Discussion

Codesize for some reason doesn't work for me. Can someone make a GUI version of it? It isn't too hard with Swing. (I've made a compression program with an algorithm of my own invention with a Swing GUI.) Or could someone post a javascript that detects it (the size) after you paste code in? Thanks! --Awesomeness 21:05, 13 March 2009 (UTC)

All you need to do to run the code size utility is "java -jar /path/to/it/codesize.jar /path/to/my/class.class". If you still can't get that working or just find it easier, you can use the "Package robot for upload" feature of Robocode which will tell you what the codesize is. Note, it's impossible for a javascript to easily detect the codesize of pastes java source code, because it's measured from the compiled bytecode not the source. --Rednaxela 21:16, 13 March 2009 (UTC)

Reducing Code Size

Well, I have a strong nano but it's roughly 280 in code size. I know I can shrink it... I'm just not very good at it. This method takes like twenty codesize points, (that's what I'll call them) and I SERIOUSLY need to shrink it. Any help please?

Code:

	public void alternate() {
		i();
		if (alternate) {
			alternate = false;
			i();
			return;
		}
			alternate = true;
	}

At least I TRIED to shrink it!


lolz,

--Awesomeness 01:22, 18 March 2009 (UTC)

The following is probably smaller codesize, but I haven't tested:

	public void alternate() {
		i();
		alternate = !alternate;
		if (!alternate) {
			i();
		}
	}

I'm not sure what i() does but I wonder if running it twice is REALLY a necessity, or if it could be worked around with very little codesize cost. Also, if codesize is critical, as it usually is for nanos, I'd suggest trying to reduce the number of number of methods in your code. If you have any methods in your code that are only called once, stop making it a seperate method. Some other tips are here in case you haven't see that. It would be easier to help if we could see more of the code, though I do have the suspicion that the biggest thing causing large codesize right now is that you may have too many methods. --Rednaxela 02:04, 18 March 2009 (UTC)

This may be even smaller

	public void alternate() {
		i();
		if (!(alternate = !alternate)) {
			i();
		}--~~~~
	}

--zyx 06:36, 18 March 2009 (UTC)

  • Maybe, but I thought I tested that type of modification to not actually be helpful despite it's common usage in nanos. Doesn't hurt to test that though, I may be wrong. --Rednaxela 07:00, 18 March 2009 (UTC)
  • I have found that this type of modifications can help, but only sometimes. I think, that how many times(or some other factors) you use the same variable again affect how the compiler translates them or something like that. But my final conclusion on codesize is that everything has to be tested, because it is really hard to know before hand how it will affect codesize. --zyx 07:22, 18 March 2009 (UTC)
    • What affects it is if you have to switch between variables. Here, the boolean alternate is being accessed 3 times in a row, so inlining it wouldn't help. However, if you called i() in between changing it and accessing it for the if then inlining would help because alternate does not have to be re-loaded into the registers. So what really matters is execution order, not whether it is inlined. Sometimes, however, it only possible to get the execution order correct by inlining. By 'correct' I mean switching between different variables as little as possible. --Skilgannon 11:15, 18 March 2009 (UTC)
  • Hm, this tempts me to try coding a nanobot using a java assembler in order to see if I can make any smaller codesize bytecode than the normal compiler would... --Rednaxela 07:35, 18 March 2009 (UTC)
  • If you really want to go that deep I recommend this book, it is the official JavaTM Virtual Machine Specification. It fully explains how a class file is encoded, there are many weird stuff in that VM. I haven't used that for codesize at all, I used it for a homework once. --zyx 07:52, 18 March 2009 (UTC)
  • As for coding java assembler ... maybe not yet for me. But looking at assembler to try to shrink is a definite yes for me. You also learn a lot of bytecode stuff from that, some of which can be guessed. (http://andrei.gmxhome.de/bytecode/index.html is super useful, it's a plugin in Eclipse that lets you view bytecode with the source) --Starrynte 00:51, 5 May 2009 (UTC)


Thank you! I've been making a nano. Yeah, two I()s are needed. I'll try these out!

Hi! There is a static final double constant that I want to be equal to 0.2. I realised, that if I write 1/5 instead of 0.2, I gain 2 bytes. But for some reason, that value of the constant will be 0.0! Do you have any idea? --HUNRobar 19:48, 28 March 2009 (UTC)

At last I figured it out. 1 and 5 are integers and for some myterious reason it calculated the value also as an integer: 0. As soon as I replaced it with 1.0/5.0, the 2 bytes came back and the constant was given the value. --HUNRobar 20:01, 28 March 2009 (UTC)

Well, wouldn't call it mysterious. All programming languages I've heard of keep integer input operators as having an integer output. One note is that 1.0/5 or 1/5.0 would also give 0.2 (no different codesize though, because the compiler optimizes 1.0/5.0 to a 0.2 in the bytecode I believe). Of course if one wants otherwise.... maybe one should design processors that have a native number format off "one sum of primes divided by another sum of primes" instead of binary integers and IEEE 754? :D --Rednaxela 20:14, 28 March 2009 (UTC)

  • Just as a footnote, in most low-level languages a/b is integer division if both a and b are integers. Integer division is a very important operation, is much faster than floating point division and you can easily tell the compiler you want floating point division ((double)a/b). Languages that perform division as floating point always are forced to offer a function to force an integer division, many times implemented as (c = a/b; return c < 0 ? ceil(c) : floor(c)) which is extremely slow, specially considering processors have a hardwired integer division operation. But I know is one of the darkest bugs one can have, a good exercise is to always check when you are going to divide if it is an integer division or not what you want. --zyx 00:23, 29 March 2009 (UTC)

I'm going mad, because I squeezed my nano from 263 bytes to 251, and I've stuck with the last two for an hour! --HUNRobar 20:59, 28 March 2009 (UTC)

Haha, I've sometimes had times like that, though I don't do codesize restricted bots much. If you update/post your bot's code on it's page and mention which one it is, people might have codesize suggestions to offer. :) --Rednaxela 21:21, 28 March 2009 (UTC)


-- Ok, I've found a new issue. I have a bot that my local codesize utility is reporting at 249, but the robocode built in version is showing 336. I'm wondering if I'm missing something. I'll go double check and make sure I have the latest codesize.jar in my test batch file. --Miked0801 00:35, 13 May 2009 (UTC)

Never mind - I had multiple classes... --Miked0801 03:09, 13 May 2009 (UTC)

I just discovered that setting my number of bins to 255 in Toorkild saves me 2 bytes over the old 230 I had before. Odd... --Skilgannon 10:26, 5 November 2009 (UTC)

Perhaps loading 255 (1111 1111) costs a little less than 230 (1110 0110)? Or you have reduced somewhere and you haven't noticed? --Nat Pavasant 12:58, 5 November 2009 (UTC)

If the bins number is an integer, then probably you reduced somewhere else (since from my tests they are both the same, since they both use SIPUSH). The only other possibility I can think of is that jikes somehow compiled 230 with SIPUSH, and 255 with LDC. For whatever reason, codesize thinks LDC is smaller than SIPUSH, though the bytecode reference says SIPUSH is smaller. --Starrynte 03:25, 6 November 2009 (UTC)

I went through it very carefully, that was the only change I made. And it's only 255. 256 comes out with an extra 2 bytes, as does 254. It's using less bytes than it would to load 0. I can't see any other code that would simplify for 255. The only way I can get a lower codesize is by using 1, and that's because two doubles simplify to 0 later on , ie. ((BINS-1)/(2*Math.PI)) = 0 when BINS = 1. If you want to experiment Toorkild 0.2.2 is the bot I noticed it in. --Skilgannon 12:13, 6 November 2009 (UTC)

ASM (byte code manipulation)

This library for direct manipulation of Java byte code looks interesting: OW2: ASM. (I know people have mentioned this kind of thing re: Mini/Micro/NanoBots before, but I don't know what other tools are out there, so just thought I'd share.) --Voidious 15:34, 24 May 2010 (UTC)

I believe there is Jusmin Java Assembler. Look like they serve the same purpose, though. --Nat Pavasant 07:36, 25 May 2010 (UTC)