Difference between revisions of "Code Size"

From Robowiki
Jump to navigation Jump to search
m (clean up a bit, remove stub)
(merged some informations - added terminology links)
Line 2: Line 2:
 
: <small>''Byte redirects here, for other uses see [[Byte (disambiguation)]]''</small>
 
: <small>''Byte redirects here, for other uses see [[Byte (disambiguation)]]''</small>
  
Code Size, defined by [[Code Size (utility)]], defines the [[Weight Class]] for [[Twin Duel]] teams (1999 bytes or less), [[:Category:MiniBots|MiniBots]] (1499 bytes or less), [[:Category:MicroBots|MicroBots]] (749 bytes or less), and [[:Category:NanoBots|NanoBots]] (249 bytes or less). It represents the amount of executing code in a .class file or .jar -- i.e., variable names and string literals are not relevant.
+
== General ==
 +
 
 +
It represents the amount of executing code in a .class file or .jar. Code size is important to you if you want to make Robots for the smaller weight classes. It can be challenging, educational, frustrating or all at once to reduce the code to the targeted level. It is not unusual that you spend hours just to find one measly byte or have to reshuffle your ideas because they won't fit the restricted weight class.
 +
This page gives you an overview of  how to reduce your code,  the utilities to measure the size,  the weight classes and some common tricks.
 +
 
 +
== How to measure ==
 +
 
 +
The Robocode client is one option to measure the size of your robot. You can do this if you "Package robot for upload" from the "Robots" menu. If you packed your robot successfully the client will show you the size with a little message window.
 +
 
 +
Another option to make the code size measuring a little more handy, is to use the [[Code_Size_(utility)|Code Size Utility]] straight within your eclipse configuration or from the console.
 +
 
 +
<!--TODO: (some steps, maybe a little tutorial) -->
 +
 
 +
== Weight Classes ==
 +
 
 +
Weight classes apply for 1v1 and for melee rumble the same.
 +
 
 +
:{| width="100%"
 +
! scope="col" width="10%"  align="left"| Class
 +
! scope="col" width="60%" align="left" | Code Size
 +
|-
 +
| General || no restrictions
 +
|-
 +
| [[:Category:MiniBots|MiniBots]] || 1499 bytes or less
 +
|-
 +
|[[:Category:MicroBots|MicroBots]] || 749 bytes or less
 +
|-
 +
|[[:Category:NanoBots|NanoBots]] || 249 bytes or less
 +
|-
 +
| [[Twin Duel]] || 1999 bytes or less ( this means two instances of one bot 1999 bytes, or instance of bot one + instance of bot two = 1999 bytes)
 +
|-
 +
| [[Team]] || no restrictions
 +
|}
 +
 
 +
== Common Tricks ==
 +
<div style="background-color:#060; font-size:1px; height:8px; border:1px solid #AAAAAA; -moz-border-radius-topright:0.5em; -moz-border-radius-topleft:0.5em;"></div>
 +
<div style="background-color:#FFFFFF;border:1px solid #AAAAAA; border-top:0px solid white; padding:5px 5px 0 5px; margin-bottom:3ex">
 +
<center>
 +
<big style="color: #000; display: block; background: #cfc; border:solid 1px #060;padding: 0.3em;">'''Code Size Cheat sheet'''</big>
 +
 
 +
{| style="width: 100%; vertical-align:top;"
 +
| style="width: 60%; vertical-align:top; border-right: 1px solid #aaa" |
 +
{| width="100%" cellpadding="2" cellspacing="5" style="vertical-align:top;"
 +
|-
 +
| style="margin:0; background:#e0efef; border:1px solid #a3bfb1; font-weight: bold; text-align:left; color:#000; padding:0.1em 0.4em;" | Use Exceptions
 +
|-
 +
|style="text-align:justify"|
 +
Do this:
 +
<syntaxhighlight>
 +
LinkedList list;
 +
  try{
 +
  someFunction
 +
    (list.getFirst());
 +
  } catch(Exception ex){}
 +
</syntaxhighlight>
 +
Don't do this:
 +
<syntaxhighlight>
 +
LinkedList list;
 +
  if(list.size() != 0){
 +
  someFunction
 +
    (list.getFirst());
 +
  }
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
|-
 +
| style="margin:0; background:#e0efef; border:1px solid #a3bfb1; font-weight: bold; text-align:left; color:#000; padding:0.1em 0.4em;" | Don't use if ... else ...
 +
|-
 +
|style="text-align:justify"|
 +
Do this:
 +
<syntaxhighlight>
 +
int i = 1;
 +
  if (j > 2) {
 +
  i = -1;
 +
  }
 +
</syntaxhighlight>
 +
Don't do this:
 +
<syntaxhighlight>
 +
int i;
 +
  if (j > 2) {
 +
  i = -1;
 +
  } else {
 +
  i = 1;
 +
  }
 +
</syntaxhighlight>
 +
 
 +
|-
 +
| style="margin:0; background:#e0efef; border:1px solid #a3bfb1; font-weight: bold; text-align:left; color:#000; padding:0.1em 0.4em;" | Declare variables on its first use
 +
|-
 +
|style="text-align:justify"|
 +
Do this:
 +
<syntaxhighlight>
 +
  double a;
 +
  double t = getEnergy() * (a = e.getBearing());
 +
</syntaxhighlight>
 +
Don't do this:
 +
<syntaxhighlight>
 +
double a = e.getBearing();
 +
  double t = a * getEnergy();
 +
</syntaxhighlight>
 +
 
 +
|-
 +
| style="margin:0; background:#e0efef; border:1px solid #a3bfb1; font-weight: bold; text-align:left; color:#000; padding:0.1em 0.4em;" | A magic of registers
 +
|-
 +
|style="text-align:justify"|
 +
Every operation to anything must be done from register. Java has 4 registers to hold variable. If the method is not static, the first one is <code>this</code> reference. The remaining registers will be use for each parameter and variable inside method. Every type of variable use 1 register, except double use 2. When 3 registers are already used by other variable, a double value will then be assigned an extra register (and the codesize is as if there was only 1 used). If you do any operation on any variable that is not on the register, Java will need to move that variable to the register before doing any of your operation, which costs codesize. This mean you should define most-used variables before any other variables.
 +
 
 +
Do this:
 +
<syntaxhighlight>
 +
public void onScannedRobot(ScannedRobotEvent e) {
 +
  int int_variable_if_you_want;
 +
  double bearing = 
 +
    e.getBearingRadians() + getHadingRadians();
 +
  double distance = e.getDistance();
 +
  // ...
 +
}
 +
</syntaxhighlight>
 +
Don't do this:
 +
<syntaxhighlight>
 +
public void onScannedRobot(ScannedRobotEvent e) {
 +
  double distance = e.getDistance();
 +
  int int_variable_if_you_want;
 +
  double bearing =
 +
    e.getBearingRadians() + getHadingRadians();
 +
  // ...
 +
}
 +
</syntaxhighlight>
 +
 
 +
|-
 +
| style="margin:0; background:#e0efef; border:1px solid #a3bfb1; font-weight: bold; text-align:left; color:#000; padding:0.1em 0.4em;" | Loop with while
 +
|-
 +
|style="text-align:justify"|
 +
You should always end up with less code size if you switch your for{each}( ...) loops to while loops. This applies to Lists as well to Arrays, just put an try..catch.. around the while to save the null, zero or "array out of bound" check.
 +
 
 +
Do this:
 +
<syntaxhighlight>
 +
public void onScannedRobot(ScannedRobotEvent e) {
 +
    try {
 +
        Iterator<your_class> iter = yourList.iterator();
 +
while(true) {
 +
            your_class obj = iter.next();
 +
          ......   // your code
 +
        }
 +
    } catch (Exception e) {}
 +
 
 +
}
 +
</syntaxhighlight>
 +
 
 +
Don't do this: (8 byte more)
 +
<syntaxhighlight>
 +
public void onScannedRobot(ScannedRobotEvent e) {
 +
    foreach(your_class obj: yourList) {
 +
      ...... // your code
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
 
 +
|}
 +
| style="width: 40%; vertical-align:top;" |
 +
{| cellpadding="2" cellspacing="5" style="width: 100% vertical-align:top;"
 +
| style="margin:0; background:#e0efef; border:1px solid #a3bfb1; font-weight: bold; text-align:left; color:#000; padding:0.1em 0.4em;" | Cost
 +
|-
 +
|
 +
{|
 +
| '''Operation'''                        ||style="text-align:right"| '''Cost in bytes'''
 +
|-
 +
| creating a class                        ||style="text-align:right"| 5
 +
|-
 +
| creating a interface      || style="text-align:right"| free
 +
|-
 +
| implementing a interface || style="text-align:right"| 1
 +
|-
 +
| 1st constructor                        ||style="text-align:right"| free
 +
|-
 +
| creating a method                      ||style="text-align:right"| free
 +
|-
 +
| returning from a method                ||style="text-align:right"| 1
 +
|-
 +
| calling a method                        ||style="text-align:right"| 3
 +
|-
 +
| storing a local (non-register) variable ||style="text-align:right"| 1
 +
|-
 +
| loading a local (non-register) variable ||style="text-align:right"| 1
 +
|-
 +
| storing a static variable              ||style="text-align:right"| 2
 +
|-
 +
| loading a static variable              ||style="text-align:right"| 2
 +
|-
 +
| loading integer literals -1 to 5        ||style="text-align:right"| 1
 +
|-
 +
| loading integer literals -128 to 127    ||style="text-align:right"| 2
 +
|-
 +
| loading integer literals -32768 to 32767 ||style="text-align:right"| 3
 +
|-
 +
| loading other integer literals          ||style="text-align:right"| 2
 +
|-
 +
| loading double literals 0, 1            ||style="text-align:right"| 1
 +
|-
 +
| loading double literals -1, 2, 3, 4, 5  ||style="text-align:right"| 2
 +
|-
 +
| loading other double literals          ||style="text-align:right"| 3
 +
|-
 +
| loading string literals                ||style="text-align:right"| 2
 +
|-
 +
| declaring a variable                   ||style="text-align:right"| free
 +
|-
 +
| casting                                ||style="text-align:right"| 1
 +
|-
 +
| promotion                              ||style="text-align:right"| 1
 +
|-
 +
| arithmetic                              ||style="text-align:right"| 1
 +
|-
 +
| ++ and -- (register or not)            ||style="text-align:right"| 1
 +
|}
 +
|}
 +
|}
 +
 
 +
</center>
 +
</div>
  
 
== See Also ==
 
== See Also ==
* [[/Cheat sheet|Cheat sheet]] on how to reduce the codesize.
+
* check the code size [[Talk:Code_Size|Discussion]] page and ask your question
 +
* many of the [[NanoBots]] and [[MicroBots]] are open source and can be used to learn more about code size reducing
 
* [[CodeSize/Old discussion]]
 
* [[CodeSize/Old discussion]]
 +
 +
== Credit ==
 +
<!-- TODO: some of the veterans maybe -->
  
  
 
[[Category:Terminology|Code Size]]
 
[[Category:Terminology|Code Size]]
 +
[[Category:Terminology|Code Size Reduce]]
 +
[[Category:Terminology|Weight Class]]

Revision as of 20:16, 18 June 2012

Code Size redirects here, for other uses see Code Size (disambiguation)
Byte redirects here, for other uses see Byte (disambiguation)

General

It represents the amount of executing code in a .class file or .jar. Code size is important to you if you want to make Robots for the smaller weight classes. It can be challenging, educational, frustrating or all at once to reduce the code to the targeted level. It is not unusual that you spend hours just to find one measly byte or have to reshuffle your ideas because they won't fit the restricted weight class. This page gives you an overview of how to reduce your code, the utilities to measure the size, the weight classes and some common tricks.

How to measure

The Robocode client is one option to measure the size of your robot. You can do this if you "Package robot for upload" from the "Robots" menu. If you packed your robot successfully the client will show you the size with a little message window.

Another option to make the code size measuring a little more handy, is to use the Code Size Utility straight within your eclipse configuration or from the console.


Weight Classes

Weight classes apply for 1v1 and for melee rumble the same.

Class Code Size
General no restrictions
MiniBots 1499 bytes or less
MicroBots 749 bytes or less
NanoBots 249 bytes or less
Twin Duel 1999 bytes or less ( this means two instances of one bot 1999 bytes, or instance of bot one + instance of bot two = 1999 bytes)
Team no restrictions

Common Tricks

Code Size Cheat sheet

Use Exceptions

Do this:

 LinkedList list;
  try{
   someFunction
     (list.getFirst());
  } catch(Exception ex){}

Don't do this:

 LinkedList list;
  if(list.size() != 0){
   someFunction
     (list.getFirst());
  }


Don't use if ... else ...

Do this:

 int i = 1;
  if (j > 2) {
   i = -1;
  }

Don't do this:

 int i;
  if (j > 2) {
   i = -1;
  } else {
   i = 1;
  }
Declare variables on its first use

Do this:

  double a;
  double t = getEnergy() * (a = e.getBearing());

Don't do this:

 double a = e.getBearing();
  double t = a * getEnergy();
A magic of registers

Every operation to anything must be done from register. Java has 4 registers to hold variable. If the method is not static, the first one is this reference. The remaining registers will be use for each parameter and variable inside method. Every type of variable use 1 register, except double use 2. When 3 registers are already used by other variable, a double value will then be assigned an extra register (and the codesize is as if there was only 1 used). If you do any operation on any variable that is not on the register, Java will need to move that variable to the register before doing any of your operation, which costs codesize. This mean you should define most-used variables before any other variables.

Do this:

public void onScannedRobot(ScannedRobotEvent e) {
  int int_variable_if_you_want; 
  double bearing =  
    e.getBearingRadians() + getHadingRadians();
  double distance = e.getDistance();
  // ...
}

Don't do this:

public void onScannedRobot(ScannedRobotEvent e) {
  double distance = e.getDistance();
  int int_variable_if_you_want; 
  double bearing = 
    e.getBearingRadians() + getHadingRadians();
  // ...
}
Loop with while

You should always end up with less code size if you switch your for{each}( ...) loops to while loops. This applies to Lists as well to Arrays, just put an try..catch.. around the while to save the null, zero or "array out of bound" check.

Do this:

public void onScannedRobot(ScannedRobotEvent e) {
    try {
        Iterator<your_class> iter = yourList.iterator();
	while(true) {
            your_class obj = iter.next();
           ......   // your code
        }	
    } catch (Exception e) {}

}

Don't do this: (8 byte more)

public void onScannedRobot(ScannedRobotEvent e) {
    foreach(your_class obj: yourList) {
       ...... // your code
    }
}


Cost
Operation Cost in bytes
creating a class 5
creating a interface free
implementing a interface 1
1st constructor free
creating a method free
returning from a method 1
calling a method 3
storing a local (non-register) variable 1
loading a local (non-register) variable 1
storing a static variable 2
loading a static variable 2
loading integer literals -1 to 5 1
loading integer literals -128 to 127 2
loading integer literals -32768 to 32767 3
loading other integer literals 2
loading double literals 0, 1 1
loading double literals -1, 2, 3, 4, 5 2
loading other double literals 3
loading string literals 2
declaring a variable free
casting 1
promotion 1
arithmetic 1
++ and -- (register or not) 1

See Also

Credit