SlideShare a Scribd company logo
Pruning your code
COP – Session 3
20 April 2018
FR van Biljon
Garden 1
Garden 2
Garden 3
My garden
Starting out
1 Year Later
Gardening 101 - Pruning
 When you plant prune 2 thirds of the plant.
 If in times of drought – prune your plants, will make them use less water.
 Pruning will encourage plants to bush – more flowers.
 Pruning will yield more fruit.
 Maintenance is easier.
 Enhance overall aesthetics.
 Improve shaping of plants.
 Dead leaves are easier to spot and get rid of.
 Layout of garden becomes easier to understand.
The best investment you can make in your
garden is pruning
~Ouma Phia Venter
How does this translate to coding?
 We forget to "prune" our code -
 We are allowing our code to branch freely
 We need to remove unnecessary branching
 We are overusing if- and switch-statements
 We are using conditional statements for business logic
 Maintenance is more complex
 Code becomes more difficult to understand
GoTo
What's your view?
 Most programmers will agree that properly written, well-structured, code
doesn't require the use of goto.
 Use of goto can lead to programs that are extremely difficult to comprehend
and analyse, and possibly to unspecified behavior.
 Lead to spaghetti code
Spot the GoTo:
private boolean processTransaction(Transaction trans) {
// do some session security checking
User user = trans.user;
log("security check for user " + user.name);
if ( user.loggedIn() == false)
return false;
if ( user.sessionTimeout() == true )
return false;
boolean success = true;
// process transaction here
return success;
}
The prisoner falls in love with his
chains...
~Dijkstra
Why is branching bad?
 Branches are GOTO statements at heart – telling the CPU where the next
instruction is. (IF condition THEN goto label)
 Branching is expensive on the CPU.
 It can lead to the arrow-antipattern
if
if
if
if
do something
endif
endif
endif
endif
Arrow Anti-Pattern
Why is branching bad?
 When the processor sees a branch instruction appear in its pipeline, it needs
to figure out how to continue to fill up its pipeline.
 In order to figure out what instructions come after the branch in the program
stream, it needs to know two things:
 if the branch will be taken and
 the target of the branch.
 Figuring this out is called branch prediction, and it's a challenging problem.
 If the processor guesses correctly, the program continues at full speed.
 If instead the processor guesses incorrectly, it just spent some time
computing the wrong thing.
 It now has to flush its pipeline and reload it with instructions from the correct
execution path.
 Bottom line: a big performance hit.
Getting rid of branches
Benefits of pruning your code
 Easier to read
 Easier to understand
 Easier to test
 Easier to maintain
 Easier to extend
 Performance gain
 ...
Over-pruning
 Like plants – don't over prune
 Can use conditional statements for primitives e.g.:
 <, >, ==, !=
 Be pragmatic – you will still have some here and there
Challenge accepted?
Create a project without IF- or SWITCH-statements
When to get rid of IF-Statements
 State Based Behavior
 Condition chooses behavior based on type or value of object
 Repeated Conditions
 Same conditional statement appears multiple times in your code
State Based
Behavior
Model This: 1 + 2 * 3
Model 1 + 2 * 3:
+
1 *
2
3
With Conditionals:
class Node{
char operator;
double value;
Node left;
Node right;
double evaluate(){
switch(operator){
case '#':return value;
case '+':return left.evaluate() + right.evaluate();
case '*':return left.evaluate() * right.evaluate();
case ... //All other operators.
}
}
}
With Polymorphism:
abstract class Node{
abstract double evaluate();
}
class ValueNode extends Node{
double value;
double evaluate(){
return value;
}
}
With Polymorphism:
abstract class OpNode extends Node{
Node left;
Node right;
abstract double evaluate();
}
class AdditionNode extends OpNode{
double evaluate(){
return left.evaluate() + right.evaluate();
}
}
class MultiplicationNode extends OpNode{
double evaluate(){
return left.evaluate() * right.evaluate();
}
}
Switch over
With Switch-statement:
class Bird {
//...
double getSpeed() {
switch (type) {
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed() - getLoadFactor() * numberOfCoconuts;
case NORWEGIAN_BLUE:
return (isNailed) ? 0 : getBaseSpeed(voltage);
}
throw new RuntimeException("Should be unreachable");
}
}
With Polymorphism:
abstract class Bird {
//...
abstract double getSpeed();
}
With Polymorphism:
class European extends Bird {
double getSpeed() {
return getBaseSpeed();
}
}
class African extends Bird {
double getSpeed() {
return getBaseSpeed() - getLoadFactor() * numberOfCoconuts;
}
}
class NorwegianBlue extends Bird {
double getSpeed() {
return (isNailed) ? 0 : getBaseSpeed(voltage);
}
}
// Somewhere in client code
speed = bird.getSpeed();
Take note:
 Polymorphism is often better
 Can add new behavior without having source code.
 You don't always have to recompile the whole code base.
 Each concern is separated (improves testability/readability/easier to understand)
Repeated
Conditions
Example:
class Update(){
execute(){
if(FLAG_i18n_ENABLED){
//DO A
}else{
//DO B
}
}
}
Example Extended:
class Update(){
execute(){
if(FLAG_i18n_ENABLED){
//DO A
}else{
//DO B
}
}
render(){
if(FLAG_i18n_ENABLED){
//render A
}else{
//render B
}
}
}
Example Extended:
class Update(){
execute(){
if(FLAG_i18n_ENABLED){
//DO A
}else{
//DO B
}
}
render(){
if(FLAG_i18n_ENABLED){
//render A
}else{
//render B
}
}
}
void testExecuteDoA{
FLAG_i18n_ENABLED = true;
Update u = new Update();
e.execute();
assertX();
}
void testExecuteDoB{
FLAG_i18n_ENABLED = false;
Update u = new Update();
e.execute();
assertX();
}
How do we test this?
How to solve this?
 Replace conditionals with a polymorphic design
 Behavior is dictated by the type of an object
 Move each leg of the conditional to an overriding method or subclass. Make
original methods abstract.
Example Extended:
abstract class Update{//..}
class I18NUpdate extends Update{
execute(){
// Do A
}
render(){
// Do A
}
}
class NonI18NUpdate extends Update{
execute(){
// Do B
}
render(){
// Do B
}
}
Testing simplified:
void testExecuteDoA{
Update u = new I18NUpdate();
u.execute();
assertX();
}
void testExecuteDoB{
Update u = new NonI18NUpdate();
u.execute();
assertX();
}
What happened to the ifs?
 In this case an if is not easily avoidable.
 We still need to know which version to instantiate?
 We can move it from being inline.
 Can we use dependency injection to solve this?
class Consumer{
Consumer(Update u){...}
}
Consider your app in two piles
 Responsible for:
 Business logic
 Domain logic
 Abstractions
Pile of Objects Pile of Construction
 Responsible for:
 Building objects
 Building Object Graph
 How components work together to
solve a custom problem
Testing simplified:
class Factory{
Consumer build(){
Update u = FLAG_i18n_ENABLED ? new I18NUpdate() : new NonI18NUpdate();
return u;
}
}
What are the benefits?
 Conditionals are moved to one place
 Conditional duplication was removed
 Separated the concerns
 Removed the global dependency
 Opened up our application for extension
Some basic
concepts
Other examples:
Let's count how many integers are odd in this array:
const arrayOfIntegers = [1, 4, 5, 9, 0, -1, 5];
let counter = 0;
arrayOfIntegers.forEach((integer) => {
const remainder = Math.abs(integer % 2);
if (remainder === 1) {
counter++;
}
});
console.log(counter);
Other examples:
Let's count how many integers are odd in this array:
const arrayOfIntegers = [1, 4, 5, 9, 0, -1, 5];
let counter = 0;
arrayOfIntegers.forEach((integer) => {
const remainder = Math.abs(integer % 2);
counter += remainder;
});
console.log(counter);
Note: the examples above use forEach and mutate the counter variable. It is cleaner and
safer to use immutable methods instead. This if-less solution would only work for
integers while the if-based solution has the advantage of handling any number
including decimal ones
Other examples:
Write a function that takes a date object argument (like new Date()) and
returns the string “weekend” or “weekday”.
const weekendOrWeekday = (inputDate) => {
const day = inputDate.getDay();
if (day === 0 || day === 6) {
return 'weekend';
}
return 'weekday';
};
console.log(weekendOrWeekday(new Date()));
Other examples:
Write a function that takes a date object argument (like new Date()) and
returns the string “weekend” or “weekday”.
weekendOrWeekday.labels = {
0: 'weekend',
6: 'weekend',
default: 'weekday'
};
const weekendOrWeekday = (inputDate) => {
const day = inputDate.getDay();
return weekendOrWeekday.labels[day]|| weekendOrWeekday.labels['default']
;
};
console.log(weekendOrWeekday(new Date()));
Questions?

More Related Content

PPT
Handling Exceptions In C &amp; C++ [Part B] Ver 2
PDF
Python Loops Tutorial | Python For Loop | While Loop Python | Python Training...
PDF
c++ lab manual
PPT
Handling Exceptions In C &amp; C++[Part A]
DOCX
C++ lab assignment
PDF
Preprocessor directives
PPT
Lecture 2
PDF
Tesseract. Recognizing Errors in Recognition Software
Handling Exceptions In C &amp; C++ [Part B] Ver 2
Python Loops Tutorial | Python For Loop | While Loop Python | Python Training...
c++ lab manual
Handling Exceptions In C &amp; C++[Part A]
C++ lab assignment
Preprocessor directives
Lecture 2
Tesseract. Recognizing Errors in Recognition Software

What's hot (13)

PPTX
Python Functions 1
PPTX
CodeChecker summary 21062021
PDF
PPT
PPTX
Cpp Homework Help
PPT
Python week 5 2019-2020 for G10 by Eng.Osama Ghandour.ppt
PDF
Python Programming | Python Programming For Beginners | Python Tutorial | Edu...
PDF
Exception Handling
PPT
Exception handler
PPTX
CPP Programming Homework Help
ODP
Refactoring Techniques
PDF
Accord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
PPT
Control Structures: Part 1
Python Functions 1
CodeChecker summary 21062021
Cpp Homework Help
Python week 5 2019-2020 for G10 by Eng.Osama Ghandour.ppt
Python Programming | Python Programming For Beginners | Python Tutorial | Edu...
Exception Handling
Exception handler
CPP Programming Homework Help
Refactoring Techniques
Accord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
Control Structures: Part 1
Ad

Similar to Pruning your code (20)

PDF
OWF12/PAUG Conf Days Pro guard optimizer and obfuscator for android, eric l...
PPSX
Complete C++ programming Language Course
PPTX
Inline function
PPTX
Best practices android_2010
PDF
4. programing 101
ODP
Simplifying RCP Update and Install
PPT
BP206 - Let's Give Your LotusScript a Tune-Up
DOCX
Function Overloading,Inline Function and Recursion in C++ By Faisal Shahzad
PPTX
Introduction to problem solving Techniques
PPTX
complier design unit 5 for helping students
PPT
3 algorithm-and-flowchart
PDF
Analyzing the Blender project with PVS-Studio
PDF
Consequences of using the Copy-Paste method in C++ programming and how to dea...
PDF
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
PDF
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...
PPTX
Improving Code Quality Through Effective Review Process
PDF
Optimization in Programming languages
PPT
Ppt lesson 06
PPT
Ppt lesson 06
OWF12/PAUG Conf Days Pro guard optimizer and obfuscator for android, eric l...
Complete C++ programming Language Course
Inline function
Best practices android_2010
4. programing 101
Simplifying RCP Update and Install
BP206 - Let's Give Your LotusScript a Tune-Up
Function Overloading,Inline Function and Recursion in C++ By Faisal Shahzad
Introduction to problem solving Techniques
complier design unit 5 for helping students
3 algorithm-and-flowchart
Analyzing the Blender project with PVS-Studio
Consequences of using the Copy-Paste method in C++ programming and how to dea...
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...
Improving Code Quality Through Effective Review Process
Optimization in Programming languages
Ppt lesson 06
Ppt lesson 06
Ad

Recently uploaded (20)

PDF
System and Network Administration Chapter 2
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
System and Network Administraation Chapter 3
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
Nekopoi APK 2025 free lastest update
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
System and Network Administration Chapter 2
Which alternative to Crystal Reports is best for small or large businesses.pdf
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
How Creative Agencies Leverage Project Management Software.pdf
System and Network Administraation Chapter 3
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Design an Analysis of Algorithms I-SECS-1021-03
Upgrade and Innovation Strategies for SAP ERP Customers
VVF-Customer-Presentation2025-Ver1.9.pptx
Nekopoi APK 2025 free lastest update
Wondershare Filmora 15 Crack With Activation Key [2025
How to Choose the Right IT Partner for Your Business in Malaysia
Odoo POS Development Services by CandidRoot Solutions
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
wealthsignaloriginal-com-DS-text-... (1).pdf
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Reimagine Home Health with the Power of Agentic AI​
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...

Pruning your code

  • 1. Pruning your code COP – Session 3 20 April 2018 FR van Biljon
  • 8. Gardening 101 - Pruning  When you plant prune 2 thirds of the plant.  If in times of drought – prune your plants, will make them use less water.  Pruning will encourage plants to bush – more flowers.  Pruning will yield more fruit.  Maintenance is easier.  Enhance overall aesthetics.  Improve shaping of plants.  Dead leaves are easier to spot and get rid of.  Layout of garden becomes easier to understand.
  • 9. The best investment you can make in your garden is pruning ~Ouma Phia Venter
  • 10. How does this translate to coding?  We forget to "prune" our code -  We are allowing our code to branch freely  We need to remove unnecessary branching  We are overusing if- and switch-statements  We are using conditional statements for business logic  Maintenance is more complex  Code becomes more difficult to understand
  • 11. GoTo
  • 12. What's your view?  Most programmers will agree that properly written, well-structured, code doesn't require the use of goto.  Use of goto can lead to programs that are extremely difficult to comprehend and analyse, and possibly to unspecified behavior.  Lead to spaghetti code
  • 13. Spot the GoTo: private boolean processTransaction(Transaction trans) { // do some session security checking User user = trans.user; log("security check for user " + user.name); if ( user.loggedIn() == false) return false; if ( user.sessionTimeout() == true ) return false; boolean success = true; // process transaction here return success; }
  • 14. The prisoner falls in love with his chains... ~Dijkstra
  • 15. Why is branching bad?  Branches are GOTO statements at heart – telling the CPU where the next instruction is. (IF condition THEN goto label)  Branching is expensive on the CPU.  It can lead to the arrow-antipattern
  • 17. Why is branching bad?  When the processor sees a branch instruction appear in its pipeline, it needs to figure out how to continue to fill up its pipeline.  In order to figure out what instructions come after the branch in the program stream, it needs to know two things:  if the branch will be taken and  the target of the branch.  Figuring this out is called branch prediction, and it's a challenging problem.  If the processor guesses correctly, the program continues at full speed.  If instead the processor guesses incorrectly, it just spent some time computing the wrong thing.  It now has to flush its pipeline and reload it with instructions from the correct execution path.  Bottom line: a big performance hit.
  • 18. Getting rid of branches
  • 19. Benefits of pruning your code  Easier to read  Easier to understand  Easier to test  Easier to maintain  Easier to extend  Performance gain  ...
  • 20. Over-pruning  Like plants – don't over prune  Can use conditional statements for primitives e.g.:  <, >, ==, !=  Be pragmatic – you will still have some here and there
  • 21. Challenge accepted? Create a project without IF- or SWITCH-statements
  • 22. When to get rid of IF-Statements  State Based Behavior  Condition chooses behavior based on type or value of object  Repeated Conditions  Same conditional statement appears multiple times in your code
  • 24. Model This: 1 + 2 * 3
  • 25. Model 1 + 2 * 3: + 1 * 2 3
  • 26. With Conditionals: class Node{ char operator; double value; Node left; Node right; double evaluate(){ switch(operator){ case '#':return value; case '+':return left.evaluate() + right.evaluate(); case '*':return left.evaluate() * right.evaluate(); case ... //All other operators. } } }
  • 27. With Polymorphism: abstract class Node{ abstract double evaluate(); } class ValueNode extends Node{ double value; double evaluate(){ return value; } }
  • 28. With Polymorphism: abstract class OpNode extends Node{ Node left; Node right; abstract double evaluate(); } class AdditionNode extends OpNode{ double evaluate(){ return left.evaluate() + right.evaluate(); } } class MultiplicationNode extends OpNode{ double evaluate(){ return left.evaluate() * right.evaluate(); } }
  • 30. With Switch-statement: class Bird { //... double getSpeed() { switch (type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * numberOfCoconuts; case NORWEGIAN_BLUE: return (isNailed) ? 0 : getBaseSpeed(voltage); } throw new RuntimeException("Should be unreachable"); } }
  • 31. With Polymorphism: abstract class Bird { //... abstract double getSpeed(); }
  • 32. With Polymorphism: class European extends Bird { double getSpeed() { return getBaseSpeed(); } } class African extends Bird { double getSpeed() { return getBaseSpeed() - getLoadFactor() * numberOfCoconuts; } } class NorwegianBlue extends Bird { double getSpeed() { return (isNailed) ? 0 : getBaseSpeed(voltage); } } // Somewhere in client code speed = bird.getSpeed();
  • 33. Take note:  Polymorphism is often better  Can add new behavior without having source code.  You don't always have to recompile the whole code base.  Each concern is separated (improves testability/readability/easier to understand)
  • 36. Example Extended: class Update(){ execute(){ if(FLAG_i18n_ENABLED){ //DO A }else{ //DO B } } render(){ if(FLAG_i18n_ENABLED){ //render A }else{ //render B } } }
  • 37. Example Extended: class Update(){ execute(){ if(FLAG_i18n_ENABLED){ //DO A }else{ //DO B } } render(){ if(FLAG_i18n_ENABLED){ //render A }else{ //render B } } } void testExecuteDoA{ FLAG_i18n_ENABLED = true; Update u = new Update(); e.execute(); assertX(); } void testExecuteDoB{ FLAG_i18n_ENABLED = false; Update u = new Update(); e.execute(); assertX(); } How do we test this?
  • 38. How to solve this?  Replace conditionals with a polymorphic design  Behavior is dictated by the type of an object  Move each leg of the conditional to an overriding method or subclass. Make original methods abstract.
  • 39. Example Extended: abstract class Update{//..} class I18NUpdate extends Update{ execute(){ // Do A } render(){ // Do A } } class NonI18NUpdate extends Update{ execute(){ // Do B } render(){ // Do B } }
  • 40. Testing simplified: void testExecuteDoA{ Update u = new I18NUpdate(); u.execute(); assertX(); } void testExecuteDoB{ Update u = new NonI18NUpdate(); u.execute(); assertX(); }
  • 41. What happened to the ifs?  In this case an if is not easily avoidable.  We still need to know which version to instantiate?  We can move it from being inline.  Can we use dependency injection to solve this? class Consumer{ Consumer(Update u){...} }
  • 42. Consider your app in two piles  Responsible for:  Business logic  Domain logic  Abstractions Pile of Objects Pile of Construction  Responsible for:  Building objects  Building Object Graph  How components work together to solve a custom problem
  • 43. Testing simplified: class Factory{ Consumer build(){ Update u = FLAG_i18n_ENABLED ? new I18NUpdate() : new NonI18NUpdate(); return u; } }
  • 44. What are the benefits?  Conditionals are moved to one place  Conditional duplication was removed  Separated the concerns  Removed the global dependency  Opened up our application for extension
  • 46. Other examples: Let's count how many integers are odd in this array: const arrayOfIntegers = [1, 4, 5, 9, 0, -1, 5]; let counter = 0; arrayOfIntegers.forEach((integer) => { const remainder = Math.abs(integer % 2); if (remainder === 1) { counter++; } }); console.log(counter);
  • 47. Other examples: Let's count how many integers are odd in this array: const arrayOfIntegers = [1, 4, 5, 9, 0, -1, 5]; let counter = 0; arrayOfIntegers.forEach((integer) => { const remainder = Math.abs(integer % 2); counter += remainder; }); console.log(counter); Note: the examples above use forEach and mutate the counter variable. It is cleaner and safer to use immutable methods instead. This if-less solution would only work for integers while the if-based solution has the advantage of handling any number including decimal ones
  • 48. Other examples: Write a function that takes a date object argument (like new Date()) and returns the string “weekend” or “weekday”. const weekendOrWeekday = (inputDate) => { const day = inputDate.getDay(); if (day === 0 || day === 6) { return 'weekend'; } return 'weekday'; }; console.log(weekendOrWeekday(new Date()));
  • 49. Other examples: Write a function that takes a date object argument (like new Date()) and returns the string “weekend” or “weekday”. weekendOrWeekday.labels = { 0: 'weekend', 6: 'weekend', default: 'weekday' }; const weekendOrWeekday = (inputDate) => { const day = inputDate.getDay(); return weekendOrWeekday.labels[day]|| weekendOrWeekday.labels['default'] ; }; console.log(weekendOrWeekday(new Date()));