I've been learning processing for the last week or two, and I've made a couple of little 'desktop toy' type apps like this one that I'm quite pleased with. However, it just occurred to me today to look in activity monitor while my app was running, and I was unpleasantly surprised  nobody wants a desktop toy that's consuming more resources than anything else on the system. So far throughout my coding education/experience I've been told not to worry about optimisation 'yet', and haven't really been offered much guidance re: efficient coding (faculty are mainly interested in code that's easy to mark)  however I think in light of this resource-hog maybe the time has come to get serious and nominate myself to get utterly demolished by the stackexchange community.Here's what the app is presenting to the user: versus the resources it's consuming:The source is in two parts, the main .pde, and another containing the 'Gua' (hexagram) class.yijingClock.pdePGraphics mins;PGraphics hrs;float fadeAmount;static final float fadeMax = 1440; //1440 means 1 step per frame takes 1 minute at 24fpsvoid setup() {  size(500, 500);  colorMode(RGB, 255, 255, 255, fadeMax);  background(255);  imageMode(CENTER); // All images in the sketch are drawn CENTER-wise  frameRate(24); // Affects the smoothness and speed of fade();  mins = createGraphics(width, height);  hrs = createGraphics(width, height);  noFill();  stroke(100);  //polygon(5, width/2, height/2, width / 4 * 3, height / 4 * 3, -PI / 2); // Draw a static pentagon as the background  fill(0);  fadeAmount = 0;} // end setup()void draw() {  //let's fade instead of redrawing the background to expose change over time  fadeAmount = map(System.currentTimeMillis() % 60000, 0, 60000, 1, fadeMax); // new way explicitly ties the fade amount to the real current second  //println(fadeAmount);  fade(fadeAmount);  drawMins();  drawHrs();}// end draw()void drawMins() {  Gua gua = new Gua(minute());  mins = gua.drawGua(color(0, 0, 0, constrain(fadeAmount*2, 100, fadeMax)));  image(mins, width/2.0, height/2.0, width/2.5, height/2.5);}// end drawMins()void drawHrs() {  float angle = TWO_PI / 5; // To arrange them in a pentagon  float startAngle = -PI / 2; // To put the first point at the top  String binHr = binary(hour(), 5); // Use modulo 12 if we want 12 hour time, but that's a waste of bits imo  char[] binHrArr = reverse(binHr.toCharArray()); // We're reversing this to match the endianness of the yijing, and the arrangement of a clock.  hrs = createGraphics(width, height); // Clearing the previous state  hrs.beginDraw();  hrs.clear(); // Trying to make the background transparent so we can layer things  hrs.imageMode(CENTER);  for (int i = 4; i >= 0; i--) {    PGraphics bit = hourBit(binHrArr[i]);    hrs.image(bit, width/2 + (width/2.1) * cos(startAngle + angle * i),      height/2 + (height/2.1) * sin(startAngle + angle * i),      25, 25);  } // end for  hrs.endDraw();  image(hrs, width/2, height/2, (width/4)*3, (height/4)*3);}// end drawHrs()// Returns a full circle for true and a hollow one for falsePGraphics hourBit(char state) {  PGraphics bit = createGraphics(40, 40);  bit.beginDraw(); // Start drawing to this buffer...  bit.imageMode(CENTER);  //bit.clear();  bit.stroke(0);  // Fill colour based on state, 1 = filled.  if (state == '1') {    bit.fill(0, fadeAmount); // They fade in  } else {    bit.fill(255);  } // end if  bit.ellipse(20, 20, 30, 30);  bit.endDraw();  return bit;} // end hourBit()/** Copypasted from https://processing.org/tutorials/anatomy/ Originally i was drawing a pentagon but mainly i just needed to learn how to get the coordinates of the points. **/void polygon(int n, float cx, float cy, float w, float h, float startAngle) {  float angle = TWO_PI/ n;  // The horizontal radius is one half the width,  // the vertical radius is one half the height  w = w / 2.0;  h = h / 2.0;  beginShape();  for (int i = 0; i < n; i++) {    vertex(cx + w * cos(startAngle + angle * i),      cy + h * sin(startAngle + angle * i));  }  endShape(CLOSE);}/** Draws a semitransparent background, which fades everything on screen by a given amount **/void fade(float amount) {  fill(255, amount); // hardcoding bc 1. im lazy, and 2. this sketch should always be b/w  rectMode(CENTER);  rect(width/2, height/2, width, height);}// end fadeGua.pdeclass Gua {  int[] yao = new int[6];  PImage img;  int intValue = 0; // Used to cast the binary to base 10 to represent the hexagram that way  static final int height = 300; // Need a good alternative to using these constants here...   static final int width = 300;  static final int lineHeight = height / 12; // the height of a line; voids are equal height to lines  static final int segmentSize = width / 5; // Used to determine the ratio of line to white in yin line; must be an odd number to allow middle to be empty  private int x = 0; // remember that (0,0) is the top left corner. Not using x really.  private int y = 0; // Used when moving down the hexagram while drawing it  /**   Default constructor instantiates a random hexagram. This hexagram exists in the memory,  and must be drawn to the canvas in a seperate operation.   **/  Gua() {    for (int i = 0; i < 6; i++) {      yao[i] = round(random(0, 1));      //print(yao[i]);    }    //println();  } // end Gua()  // Construct a hexagram with a given (base 10) value.  Gua(int value) {    String binary = binary(value, 6);    //println(parsed binary:  + binary);    for (int i = 0; i < binary.length(); i++) {      yao[i] = Character.getNumericValue(binary.charAt(i));      //print(yao[i]);    }        //println();  } // end Gua(int)  // Convenience version comes in black  PGraphics drawGua() {    return drawGua(color(0,0,0));  } // end drawGua()/** Draw a gua of a given colour **/  PGraphics drawGua(color col) {    PGraphics pg = createGraphics(width, height); // the image buffer we will return    pg.beginDraw();    //pg.clear();    pg.noStroke();    pg.fill(col);    //pg.background(255, alpha(col));    int i = 5; // we have to read them backwards because tradition places the smallest bit at the top    for (y = 0; y <= 250; y = y + 50) {      if (yao[i] == 0) { // yin                pg.rect(x, y, (segmentSize * 2), lineHeight); // left side        pg.rect(segmentSize * 3, y, (segmentSize * 2), lineHeight); // right side        //println(-- --);      } // end if      else { // yang        pg.rect(x, y, width, lineHeight);        //println(-----);      } // end else      i--;    } //end for    pg.endDraw();    return pg;  }// end drawGua(colour)  String toString() {    return join(str(yao), );  }// end toString()  int toInt() {    return unbinary(toString());  }// end toInt()} // End GuaI probably don't need to point out that I'm a total beginner, so please, even the most obvious optimisation tips would be appreciated. If the answer is that I've written everything totally wrong and should start over, honestly that would be even better, as I feel I need to start developing good habits asap.
Binary/yijing clock in Processing with excessive resource consumption
java;performance;processing
Something you need to learn about performance in java is that if performance is important to you, Java might not be the language for you. Your code is not directly translated into machine code; the compiler interprets your code, rewrites it with it's own optimization algorithms before translating it to machine code. Of course you can make minor changes to your code to make slight performance improvements, but on a general scale going for performance means it becomes more of a game of how to trick the compiler rather than pure performance increase through code.To your actual codeCommentsYou're commenting way too much. If this is for your own learning process and noone else have to look at the code, that's fine,  but if this is code you are gonna share, commenting near every line is only gonna make it hard to read quite annoying. Anyone who didn't pick up coding 2 weeks ago don't need to see // end methodName(). You should only write comments when your code does something that's not obvious just by reading it. You're not making a tutorial for people who can't read code, you're writing comments to clarify difficult parts to yourself and your colleagues.JavaDoc are actually quite useful if you do them right;/** * This method connects to the database and persists the ObjectType entity provided. * @param ObjectType * @return ObjectType (persisted object) */If you're using an IDE like NetBeans or IntelliJ this JavaDoc will pop up and let you know what the method does and how to use it (just like it will help anyone else using your code). However, you're not writing JavaDoc, you're writing block comments that explains the code, not documents it.You're also leaving a lot of scrap comments in your code. If you have to comment it out and it's no longer a WIP, remove unused code.Access modifiersIt's also bad practice to not add access control modifiers, if it's something you haven't studied yet you can read about it in the oracle tutorial.Magic numbers and hard-codingYou should also try to not hard-code everything. There's something called magic numbers and you're using them near everywhere. Ins this for loop you have three: for (y = 0; y <= 250; y = y + 50) {}The first one can be somewhat forgiven since index begins with 0 and there might not be any places you want to modify this, but the other two;What is 250? Where does it come from? Why is it that specific number?y = y + 50 raises the same questions.Why it's important to not use magic numbers is that a) You'll know what the number represents and it's easier to follow what you're iterating. b) The most important thing! If you need to change these numbers, you only change one variable declared at the top in the global scope, otherwise you need to somehow know and remember which magic numbers are related to this variable and has to be changed as well.And when you hard-code all the variables locally, your methods are not dynamic and can't be re-used. It might not seem to matter here, but it's a good practice to put in among your habits when coding.