I am writing a Java program to do a simple math problem and I can't find a good way to get both code readability and performance :
Given a List of Node class and initial value of rank ( a double value with some mathematical meaning ) for each Node.
Calculate new rank for each node based on old rank value using some algorithm. Use the newly calculated rank value as old value and repeat the calculation process for multiple times.
// this code snippet is pseudo code and does not compile
class Node {
private int property1;
....
private int propertyN;
.... //getters and setters
}
List<Node> nodes;
Map<Node,Double> rankold;
Map<Node,Double> ranknew;
void doOneIteration() {
foreach (node in nodes) {
ranknew.put(node,someAlgorithm(rankold));
}
rankold = ranknew;
ranknew = {};
}
void doCalcuation(int times) {
nodes = [...];
rankold = {...};
ranknew = {};
while (times-->0) {
doOneIteration();
}
}
This code snippet are easiest to read. It separates rank logic from the node classes so it's easy to maintain.
The problem is about performance.
Creating HashMap and Double instances uses some extra CPU and Memory resources. and someAlgorithm() is simple but the number of Nodes is large.
And I wrote another version without using map:
class Node {
private int property1;
....
private int propertyN;
private double rank1;
private double rank2;
.... //getters and setters
}
List<Node> nodes;
boolean useRank1 = true;
void doOneIteration() {
if (useRank1 ) {
someAlgorithmUseRank1(nodes));
} else {
someAlgorithmUseRank2(nodes));
}
useRank1 = !useRank1;
}
This code snippet minimize memory usage but I will copy code of someAlgorithm() twice and if I made any change to someAlgorithm() there are two block of code to edit and I think this is "not elegant".
Here's a third code snippet I considered:
boolean useRank1 = true;
class Node {
private double rank1;
private double rank2;
double getRank() { if (useRank1) return rank1; else return rank2;}
void setRank(double r) { if (useRank1) rank2=r; else rank1=r;}
}
List<Node> nodes;
void doOneIteration() {
someAlgorithm(nodes);
useRank1 = !useRank1;
}
The problem is that the if branch in the getter and setter will be called multiple times which is not necessary. There is branch prediction and other many runtime optimizations in modern CPU and compilers but I am not sure how good will they work. Another concern is that this code snippet slightly increase the memory use of Node class since Node will have a pointer to the class holding useRank1 (although compared to object header one pointer is small)
The question is that is there good way to write "good" code for my problem? (good at CPU & Mem, and easy to read / maintain)
Related
I have the own data structure for the graph, and I need the implementation method:
List<Edge<T>> getPath(T start, T finish)
Performance not important, I search the simplest and most readable way. But my data structure should support the directed and undirected graph types and I stuck with it.
public class Graph<T> {
private boolean isDirected = false;
private Map<Vertex<T>, List<Edge<T>>> graph = new HashMap<>();
public Graph() {
}
public Graph(boolean isDirected) {
this.isDirected = isDirected;
}
public List<Edge<T>> getPath(T start, T finish) {
if (start.equals(finish)) {
return new ArrayList<>();
}
// TODO here is the method I'm stuck with.
if (isDirected) {
// Call search for directed graph
} else {
// Call search for undirected graph
}
}
public void addEdge(T first, T second) {
final Vertex<T> master = new Vertex<>(first);
final Vertex<T> slave = new Vertex<>(second);
final Set<Vertex<T>> vertices = graph.keySet();
if (!vertices.contains(master) || !vertices.contains(slave)) {
throw new IllegalArgumentException();
}
graph.get(master).add(new Edge<>(master, slave));
if (!isDirected) {
graph.get(slave).add(new Edge<>(slave, master));
}
}
public void addVertex(T value) {
final List<Edge<T>> result = graph.putIfAbsent(new Vertex<>(value), new ArrayList<>());
if (result != null) {
throw new IllegalArgumentException();
}
}
}
This Vertex and Edge class:
#Data
#AllArgsConstructor
#EqualsAndHashCode
public class Vertex<T> {
private T value;
}
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Edge<T> {
private Vertex<T> first;
private Vertex<T> second;
}
I will be very grateful for Your help.
It is not totally clear what kind of path you want to find. The shortest path, any path,...?
If you want to find the shortest path, A* is a really simple algorithm to implement. The pseudo code can be found here. A* is a best-first search algorithm for a weighted graph (E.g. the distance of an edge or another kind of cost to travel on the edge like time). The algorithm uses a heuristic function to select the next node/vertex to evaluate. A* basically repeats the following steps:
Select a next node/vertex which has not already been visited. The selection is made using the heuristic function
If this new node equals the goal position, return the shortest path found
Evaluate all paths currently known and select the one with the lowest cost
I could also provide a Java code snippet (based on the pseudo code) if it's necessary. Be aware that the pseudo code in the end constructs the shortest path backwards (from goal to start).
You are also using a generic for your graph. Both your Vertext and Edge class use this generic. Let's assume that this generic T is a double. In your code this means that your Vertex is only a one-dimensional double. This does not make sense when you want to represent a graph of 2D or 3D points.
Is it even really necessary to use this generic? Wouldn't it be sufficient to simply support vertices which consists of floats, doubles or integers? Using a generic type or more abstract class (like Number) might give some problems when you for example want to compute the distance between vertices.
I have a "configuration" class that becomes a field of several other classes. It indicates some kind of configuration or "abilities" of those other classes to allow or disallow actions. The configuration class as of now contains a set of four independent booleans and will likely remain like that --or grow with another bolean--. The configuration is immutable: once the object is created, the configuration will never change.
public class Configuration {
private final boolean abilityOne;
private final boolean abilityTwo;
private final boolean abilityThree;
private final boolean abilityFour;
public Configuration (final boolean abilityOne, final boolean abilityTwo,
final boolean abilityThree, final boolean abilityFour) {
this.configuration = ((1 * (abilityOne ? 1 : 0)) +
(2 * (abilityTwo ? 1 : 0)) +
(4 * (abilityThree ? 1 : 0)) +
(8 * (abilityFour ? 1 : 0)));
}
public boolean isAbilityOne() {
return((1 & this.configuration) > 0);
}
public boolean isAbilityTwo() {
return((2 & this.configuration) > 0);
}
public boolean isAbilityThree() {
return((4 & this.configuration) > 0);
}
public boolean isAbilityFour() {
return((8 & this.configuration) > 0);
}
}
Because of C / limited-hardware background, my next implementation (attempt at reducing memory footprint) was with an int used as a bit map: 1 -> first boolean, 2-> second, 4 -> third, 8-> fourth. This way I store an integer and the boolean functions I needed were like:
It works fine and it is quite memory efficient. But it is frowned upon by my Java-all-my-life colleagues.
The number of different configurations is limited (the combinations of boolean values), but the number of objects using them is very large. In order to decrease memory consumption I thought of some kind of "multi-singleton", enumeration or cached instances. And this is where I am now. What is best?
I think multiton pattern is the most efficient way to do this:
public class Configuration {
private static Map<Long, Configuration> configurations = new HashMap<>();
private long key;
private long value;
public static Configuration getInstanse(long key, boolean... configs) {
if (configurations.containsKey(key)) {
return configurations.get(key).setConfigs(configs);
}
Configuration configuration = new Configuration(key, configs);
configurations.put(key, configuration);
return configuration;
}
// Max number of configs.length is 64
private Configuration(long key, boolean... configs) {
this.key = key;
setConfigs(configs);
}
private Configuration setConfigs(boolean[] configs) {
this.value = 0L;
boolean config;
for (int i = 0; i < configs.length; i++) {
config = configs[i];
this.value = this.value | (config ? (1L << i) : 0L);
}
}
public long getKey() {
return key;
}
public boolean getConfig(int place) {
return (value & (1L << place)) == (1L << place);
}
}
I would suggest the following, it is very easy to expand as you just have to add another Ability to your enum.
enum Ability {
Ability1, Ability2, Ability3, Ability4
}
public class Configuration {
private static LoadingCache<Set<Ability>, Configuration> cache = CacheBuilder.newBuilder()
.build(new CacheLoader<Set<Ability>, Configuration>() {
#Override
public Configuration load(Set<Ability> withAbilities) {
return new Configuration(withAbilities);
}
});
Set<Ability> abilities;
private Configuration(Collection<Ability> withAbilities) {
this.abilities = createAbilitySet(withAbilities);
}
public static Configuration create(Ability... withAbilities) {
Set<Ability> searchedAbilities = createAbilitySet(Arrays.asList(withAbilities));
try {
return cache.get(searchedAbilities);
} catch (ExecutionException e) {
Throwables.propagateIfPossible(e);
throw new IllegalStateException();
}
}
private static Set<Ability> createAbilitySet(Collection<Ability> fromAbilities) {
if (fromAbilities.size() == 0) {
return Collections.emptySet();
} else {
return EnumSet.copyOf(fromAbilities);
}
}
public boolean hasAbility(Ability ability) {
return abilities.contains(ability);
}
}
If the configuration implementation objects are small and not expensive to create, there is no need to cache them. Because each monster object will have to keep a reference to each of its configurations, and at machine level a reference is a pointer and uses at least the same memory as an int.
The EnumSet way proposed by #gamulf can probably be used as it without any caching, because according to EnumSet javadoc:
Enum sets are represented internally as bit vectors. This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags."
I did not benchmarked it, but caching is likely to be useless with #gamulf's solution because a Configuration object contains only an EnumSet that contains no more than an int.
If you had a heavy configuration class (in term of memory or expensive to create) and only a small number of possible configurations, you could use a static HashSet member in the class, and a static factory method that would return the cached object:
public class Configuration {
static Set<Configuration > confs = new HashSet<>();
...
public Configuration (Ability ... abs) {
...
}
public boolean hasAbility(Ability ab) {
...
}
static Configuration getConfiguration(Ability ... abs) {
for (ConfImpl2 conf: confs) {
if (conf.isSame(abs)) { return conf; }
}
ConfImpl2 conf = new ConfImpl2(abs);
confs.add(conf);
return conf;
}
private boolean isSame(Ability ... abs) {
// ensures that this configuration has all the required abilities and only them
...
}
}
But as I have already said, that is likely to be useless for objects as lightweight as those proposed by #gamulf
I want to share the investigation I made based on your answers, so I'm posting one answer with those results. This way it might be clearer why I choose one answer over other.
The bare result rank are as follows (memory used for 600 "monster" objects, 10% of what will be needed):
trivial option: Class with four booleans inside: 22.200.040
Initial option: Class with one integer as map of bits: 22.200.040
"multiton" option: one factory class that returns references to the trivial option's Class: 4.440.040
EnumSet (without guava cache): 53.401.896 (in this one I probably messed up, since results are not as expected... I might work further on this later on)
EnumSet with guava cache: 4.440.040
Since my tests run first a series of comparisons to ensure that all implementations give the exact same results for all configurations, it has become clear that the 4.440.040 number is the size of the List<> I used to hold the items, for before I resolved to set it to null before measuring memory, those numbers were consistently 0.
Please don't go into how I measured memory consumption (gc(); freeMemory(); before and after I freed each list and set it to null), since I used the same method for all, and performed 20 executions each time and in different orders of execution. Results were consistent enough for me.
These results point at the multiton solution as the easiest of the best performing. That's why I set it as the selected answer.
As side note/curiosity, please be informed that the project for which this investigation started has selected the trivial option as the solution and most of this investigation was made to satisfy my own curiosity --and with some hidden desire to be able to demonstrate that some other solution would be soooo much more efficient than the trivial one... but no--. This is why it took me so long to come up with a conclusion.
I have a player which can feed a dog or chop a tree.
Below are the classes I have written:
public class Dog {
private int health;
public void feed(Food food){
health = health + food.getNutritionalValue();
}
}
public class Player{
public void feed(Dog dog, Food food) {
dog.feed(food);
}
Player and Dog both have methods that are "active".
Player feeds the dog and dog starts eating the food (I am not really sure if it is good to couple methods in this way).
On the other hand, I have tree. And player is able to chop the tree.
public class Player{
public void chop(Tree tree) {
//At this point I am not sure
}
I am not sure if I would use getters and setters of Tree class to interact with the Tree.
Or if I should write an own method for this because the tree gets chopped so it is nothing really active I would call.
So, in the end, there would be two or more kinds of implementations but the two I am thinking of are:
tree.setAmountofWood = x
or
tree.gettingChopped(Damage int)
I think I should make an own method for this chopping-process.
Or is there any design principle I should follow?
I see 3 principles here,
SRP - It is the responsibility of the Tree to get chopped and fall down, but to cut is the responsibility of the Person!
Demeter's law - looks good from my POV.
OCP - The tree must be able to do further actions when get cut.
So you must use
tree.gettingChopped(Damage damage)
To your code:
The method Dog.feed is wrong, rename it to Dog.eat because the Dog is not feeding, the dog is eating. By the way, the food must reduce its NutritionalValue.
The health is an integer value, this is bad because in reality there is nothing like a numeral health. We may have a handicapped numeral value in percent, but this is more a byte who not can be in negative value. You should create a custom class for the Health! This way your code is open(OCP) for extensions like to be toxified or depresive.
I would start from something like this.
Tree can grow and receive damage.
public class Tree {
private int lumber;
public Tree(int size) {
this.lumber = size;
}
public void grow() {
this.lumber++;
}
public void grow(int size) {
this.lumber += size;
}
public int receiveDamage(int damage) {
int lumber = 0;
if (damage > this.lumber) {
lumber = this.lumber;
this.lumber = 0;
} else {
lumber = damage;
this.lumber -= damage;
}
return lumber;
}
}
Food just stores nutritional value.
public class Food {
private int nutrition;
public Food(int nutrition) {
this.nutrition = nutrition;
}
public int getNutritionalValue() {
return this.nutrition;
}
}
I'm not sure if all types of player can chop trees, so I created a class to separate responsibilities. You can move methods to the Player class if you like.
public class Woodcutter extends Player {
public int chop(Tree tree) {
// lumber amount may depend on a tool,
// i.e. axe, chainsaw, etc.
return tree.receiveDamage(10);
}
// fell down the tree
public int fell(Tree tree) {
int result = 0;
int lumber = 0;
do {
lumber = chop(tree);
result += lumber;
} while (lumber > 0);
return result;
}
}
Somewhere in your code
// create a tree and let it grow for a while
Tree tree = new Tree(10);
tree.grow(90);
// Start chopping
Woodcutter woodcutter = new Woodcutter();
System.out.println("Lumber received: " + woodcutter.chop(tree));
System.out.println("Lumber received: " + woodcutter.fell(tree));
Dog dog = new Dog();
Food food = new Food(5);
woodcutter.feed(dog, food);
I wouldn't dive into passive/active methods here. An 'active tree' may indeed be a misnomer.
I would rather consider calling an object's method as passing a message to the object. And you apparently need to send the message to the tree that it is currently being cut by someone, and let the tree decide when to e.g. fall() or to bend(), or to shake().
The tree has some internal state (strength? thickness of its trunk? health?). 'Sending a message' to the tree means to call its method, e.g. beingCut(), which in turn deteriorates the state of the tree. After the state of the tree reaches a certain limit, other actions (=consequences of tree's bad state) may be started by the tree.
Of course, as in every iteration of your main loop you tree has also the chance to get the message to grow(), so its state may improve a little each time, so eventually it may even recover from being only partially cut and reach its initial, perfect state back.
So, yes, while trees seem rather passive, they still react to messages/stimulus. :-)
In my current setup I'm storing my categorical enum (Defense) and value (Rank, also an enum) in a wrapper object.
public class RankedDefense implements Serializable {
private Defense defense;
private Rank rank;
public RankedDefense(Defense d, Rank r) {
defense = d;
rank = r;
}
public Defense getDefense() {
return defense;
}
public Rank getRank() {
return rank;
}
}
I then store lists of these in a data object (ScoutData). The same Defense will never be repeated in any of these lists.
The problem arises when I implement methods to organize the data from multiple ScoutData objects. I need to merge multiple lists of RankedDefenses while making sure that the same Defense is never repeated.
The only efficient way I found to do this was to repeatedly iterate over both lists and check. However, I'm not confident the method I used even works properly.
List<RankedDefense> defenses = new ArrayList<>();
for (ScoutData d : data) {
//We need to compare every item in every list
for (RankedDefense potential : d.getTeleopListDefensesBreached()) {
for (RankedDefense listItem : defenses) {
if (listItem.getDefense() == potential.getDefense()) {
defenses.add(new RankedDefense(listItem.getDefense(), Rank.NOT_ATTEMPTED)); //TODO actually average the ranks
break;
}
}
}
}
return defenses;
I can't seem to figure out where to put the line of code that adds the RankedDefense if one with the same Defense isn't already in the list.
Is there a more efficient method to store my values that would prevent this iteration headache? And if not, is there a more readable and reliable way to implement the iteration code?
Using EnumMap and changing my code accordingly has solved all my problems. It does exactly what I was looking for.
Most people understand the innate benefits that enum brings into a program verses the use of int or String. See here and here if you don't know. Anyway, I came across a problem that I wanted to solve that kind of is on the same playing field as using int or String to represent a constant instead of using an enum. This deals specifically with String.format(...).
With String.format, there seems to be a large opening for programmatic error that isn't found at compile-time. This can make fixing errors more complex and / or take longer.
This was the issue for me that I set out to fix (or hack a solution). I came close, but I am not close enough. For this problem, this is more certainly over-engineered. I understand that, but I just want to find a good compile-time solution to this, that provides the least amount of boiler-plate code.
I was writing some non-production code just to write code with the following rules.
Abstraction was key.
Readability was very important
Yet the simplest way to the above was preferred.
I am running on...
Java 7 / JDK 1.7
Android Studio 0.8.2
These are unsatisfactory
Is there a typesafe alternative to String.format(...)
How to get string.format to complain at compile time
My Solution
My solution uses the same idea that enums do. You should use enum types any time you need to represent a fixed set of constants...data sets where you know all possible values at compile time(docs.oracle.com). The first argument in String.format seems to fit that bill. You know the whole string beforehand, and you can split it up into several parts (or just one), so it can be represented as a fixed set of "constants".
By the way, my project is a simple calculator that you probably seen online already - 2 input numbers, 1 result, and 4 buttons (+, -, ×, and ÷). I also have a second duplicate calculator that has only 1 input number, but everything else is the same
Enum - Expression.java & DogeExpression.java
public enum Expression implements IExpression {
Number1 ("%s"),
Operator (" %s "),
Number2 ("%s"),
Result (" = %s");
protected String defaultFormat;
protected String updatedString = "";
private Expression(String format) { this.defaultFormat = format; }
// I think implementing this in ever enum is a necessary evil. Could use a switch statement instead. But it would be nice to have a default update method that you could overload if needed. Just wish the variables could be hidden.
public <T> boolean update(T value) {
String replaceValue
= this.equals(Expression.Operator)
? value.toString()
: Number.parse(value.toString()).toString();
this.updatedString = this.defaultFormat.replace("%s", replaceValue);
return true;
}
}
...and...
public enum DogeExpression implements IExpression {
Total ("Wow. Such Calculation. %s");
// Same general code as public enum Expression
}
Current Issue
IExpression.java - This is a HUGE issue. Without this fixed, my solution cannot work!!
public interface IExpression {
public <T> boolean update(T Value);
class Update { // I cannot have static methods in interfaces in Java 7. Workaround
public static String print() {
String replacedString = "";
// for (Expression expression : Expression.values()) { // ISSUE!! Switch to this for Expression
for (DogeExpression expression : DogeExpression.values()) {
replacedString += expression.updatedString;
}
return replacedString;
}
}
}
So Why Is This An Issues
With IExpression.java, this had to hacked to work with Java 7. I feel that Java 8 would have played a lot nicer with me. However, the issue I am having is paramount to getting my current implementation working The issue is that IExpression does not know which enum to iterate through. So I have to comment / uncomment code to get it to work now.
How can I fix the above issue??
How about something like this:
public enum Operator {
addition("+"),
subtraction("-"),
multiplication("x"),
division("÷");
private final String expressed;
private Operator(String expressed) { this.expressed = expressed; }
public String expressedAs() { return this.expressed; }
}
public class ExpressionBuilder {
private Number n1;
private Number n2;
private Operator o1;
private Number r;
public void setN1(Number n1) { this.n1 = n1; }
public void setN2(Number n2) { this.n2 = n2; }
public void setO1(Operator o1) { this.o1 = o1; }
public void setR(Number r) { this.r = r; }
public String build() {
final StringBuilder sb = new StringBuilder();
sb.append(format(n1));
sb.append(o1.expressedAs());
sb.append(format(n2));
sb.append(" = ");
sb.append(format(r));
return sb.toString();
}
private String format(Number n) {
return n.toString(); // Could use java.text.NumberFormat
}
}