My tide prediction application uses 8 double arrays for tide height calculations. Literally every tide station in the United States requires these to have 37 elements, EXCEPT Anchorage, Alaska which requires 124 elements.
Here is a declaration example
final int NUM_C = 37; //all stations except anchorage use 37
//final int NUM_C = 124; //anchorage uses 124
double a[] = new double[NUM_C + 1];
Can I efficiently specify the array size at the start up of the app? I can determine which is needed. I don't want to burden the application with inefficiency for 99% + of the users to handle this one case. The difference is only about 3K bytes.
Why don't you instantiate the variable in the constructor? It gives you more freedom to do programatic manipulation.
public class Station {
double a[];
public Station(String location) {
if(location.equals("Anchorage")) {
a = new double[124];
} else {
a = new double[37];
}
}
}
As I understand the instantiation of the object fields in the constructor is the normal case, while the instantiation with the declaration is just an additional feature of Java.
As for the speed it does not make a difference, if you specify the size by a literal value, a constant or a variable. A more interesting question is, if you should use ArrayList instead of an array. See here.
public class Station {
ArrayList<Double> a;
public Station(String location) {
if(location.equals("Anchorage")) {
a = new ArrayList<>(124);
} else {
a = new ArrayList<>(37);
}
}
}
My choice would be ArrayList as it is more flexible. Eight times 124 is not a very large number anyway. No reason to worry about performance for this.
Related
I need to sort the products by High to Low & Low to High of its Price.I have done Low to High by using following code.But dont know how to implement High To Low?
Your answer is more appreciated...
public static Comparator<Restaurant_Beam> strPriceFilterL2H = new Comparator<Restaurant_Beam>() {
#Override
public int compare(Restaurant_Beam lhs, Restaurant_Beam rhs) {
int CompareResult = 0;
if (Config.L2HFilterClicked == "L2H") {
CompareResult = (int) Math.round(Double.parseDouble(lhs.getIG_SALES_PRICE()) - Double.parseDouble(rhs.getIG_SALES_PRICE()));
}
//Used else if for H2L.But did not get it as perfect
else if (Config.L2HFilterClicked == "H2L") {
CompareResult = (int) Math.round(Double.parseDouble(lhs.getIG_SALES_PRICE()) + Double.parseDouble(rhs.getIG_SALES_PRICE()));
}
return CompareResult;
}
};
Change the second compare expression to this one:
CompareResult = (int) Math.round(Double.parseDouble(Double.parseDouble(rhs.getIG_SALES_PRICE()) - Double.parseDouble(lhs.getIG_SALES_PRICE()));
Also I'd like to point out a few things
consider doing Double comparison with epsilon
it's a good practice to check objects before comparing them
parsing each time you compare is really bad design. It would be better if you parse values somewhere in advance, consider changing your type. Currently it's not efficient.
quick question. I am developing a top-down 2d Platformer game with lots of enemies in the map (at least a hundred spawn at the start of each level). Each enemy uses an AI that searches the map for objects with a specified tag, sorts each object into a list based on their distance, then reacts to the object closest to them.
My code works, but the thing is, if the machine my game is running on is slow, then my game lags. I want to be able to port my game to Android and iOS with low end specs.
In pursuit of putting less strain on the CPU, is there a better way to write my AI?
Here is my code:
void Start () {
FoodTargets = new List<Transform>(); // my list
SelectedTarget = null; // the target the enemy reacts to
myTransform = transform;
AddAllFood ();
}
public void AddAllFood()
{
GameObject[] Foods = GameObject.FindGameObjectsWithTag("Object");
foreach (GameObject enemy in Foods)
AddTarget (enemy.transform);
}
public void AddTarget(Transform enemy)
{
if (enemy.GetComponent<ClassRatingScript>().classrating != 1) { // classrating is an attribute each enemy has that determines their identity (like if they are a plant, a herbivore or a carnivore)
FoodTargets.Add (enemy); // adds the object to the list
}
}
private void SortTargetsByDistance() // this is how I sort according to distance, is this the fastest and most efficient way to do this?
{
FoodTargets.Sort (delegate(Transform t1, Transform t2) {
return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
});
}
private void TargetEnemy() // this is called every 4 frames
{
if (SelectedTarget == null) {
SortTargetsByDistance ();
SelectedTarget = FoodTargets [1];
}
else {
SortTargetsByDistance ();
SelectedTarget = FoodTargets [1];
}
}
if (optimizer <= 2) { // this is a variable that increments every frame and resets to 0 on the 3rd frame. Only every 3rd frame is the target enemy method is called.
optimizer++;
} else {
TargetEnemy ();
// the rest are attributes that the AI considers when reacting to their target
targetmass = SelectedTarget.GetComponent<MassScript> ().mass;
targetclass = SelectedTarget.GetComponent<ClassRatingScript> ().classrating;
mass = this.GetComponent<MassScript> ().mass;
classrating = this.GetComponent<ClassRatingScript> ().classrating;
distance = Vector3.Distance (transform.position, SelectedTarget.transform.position);
optimizer = 0;
}
Is there a more optimized way of doing this? Your help will be much appreciated. Thanks in advance!
I'm not awfully familiar with C# or Unity but I would look very carefully at what sorting algorithm your sorting method is using. If all you want is the closest Game Object, then sorting isn't necessary.
The fastest sorting algorithms, such as Quicksort, are O(n*log(n)). That is to say that the time it takes to sort a collection of n objects is bounded by some constant multiple of n*log(n). If you just want the k closest objects, where k << n, then you can perform k iterations of the Bubble Sort algorithm. This will have time-complexity O(k*n), which is much better then before.
However, if you only need the single closest object, then just find the closest object without sorting (pseudocode):
float smallestDistance = Inf;
object closestObject = null;
foreach object in objectsWithTag {
float d = distance(object, enemy);
if (d < smallestDistance) {
smallestDistance = d;
closestObject = object;
}
}
This extremely simple algorithm has time complexity O(n).
I'm using the speech recognizer to get a voice input from the user, it returns an array of 5 strings which I pass to this method
public int analyzeTag(ArrayList<String> voiceResults,Editor editor, Context context){
for (String match : voiceResults) {
Log.d(TAG, match);
if (match.equalsIgnoreCase(context.getResources().getString(R.string.first_tag))){
editor.append(context.getResources().getString(R.string.first_tag));
return 1;
}
else if (match.equalsIgnoreCase(context.getResources().getString(R.string.second_tag))){
editor.append(context.getResources().getString(R.string.second_tag));
return 1;
}
//etc....(huge list of tags)
//Some tags might also have acceptable variations, example:
else if (match.equalsIgnoreCase("img") || match.equalsIgnoreCase("image")
{
editor.append("img"); //the string to append is always taken from the first variation
}
}
return 0;
}
This method compares the results with a list of tags, the tag list will be pretty big with hundreds of tags so I would like to find the most efficient way to do this operation.
I need help with:
1.Is my way of comparing results the most efficient? Is there a better way? (from the user experience perspective, I don't want users waiting a long time to get a result).
The voice input will be a big part of my app so this method will be called quite often
2.I have a long list of tags, obviously the if(), elseIf() route is gonna be quite repetitive, is there a way to iterate this? Considering the fact that some tags might have variations (even more than 1)and that the variation 1 ("img") will be the same for everyone, but other variations will be locale/language sensitive example: "image" for english users "immagini" for italian users etc.
Text appended to the editor will be always taken from the first variation
How about puting tags in a StringArray and then iterate though the array ?
String[] tags = context.getResources().getStringArray(R.array.tags);
for (String match : voiceResults) {
for (int index = 0; index < tags.length; index++ ) {
if (match.equalsIgnoreCase(tags[index]) {
editor.append(tags[index]);
}
}
}
Here's the doc on StringArray
I am in need of assistance. I will be computing a measured variable, then taking the top 100 values of these and averaging them. Please remember, I have been teaching myself only for the past 6 weeks and what is obvious to some, will not necessarily be obvious to me.
In essence, say 'double x' is the variable, that I have many close values for. What I need is a way to compute the sum (then average) of the top 100 of these values.
In my research, the closest thing I can see that would suit what I need is 'nextAfter(double start, double direction); and before this, using 'max' to determine the maximum value, would this be the correct starting point:
double xm = max(x);
static double (xm, x < xm);
My question is how to get the sum of the top 100 values (the maximum and 99 nextAfter's) - averaging would be easy - just dividing by 100.
To compute the average of the largest n values you read from the source, you need to store at least these values. Since at any given point before the end you don't know whether some of the largest n values overall will come later, you need to keep track the largest n values seen so far.
A simple way to do that is to store the largest values in a heap or priority queue, since that allows easy adding of new values and finding (and removing) of the smallest of the stored values. The default PriorityQueue is well-suited for this task, since it uses the natural ordering of the elements, and thus polling removes the smallest of the stored elements. If one wanted to compute the average of the n smallest elements, one would need to use a PriorityQueue with a custom Comparator (or in this special case, simply negating all values and using the natural ordering would work too).
The lazy way (less code) to achieve the desired is to simply add each incoming value to the queue, and if the queue's size exceeds n [then it must be n+1] remove the smallest element from the queue:
// vp is the value provider
while(vp.hasNext()) {
// read the next value and add it to the queue
pq.add(vp.nextValue());
if (pq.size() > topSize) {
pq.poll();
}
A slightly more involved way is to first check whether the new value needs to be added, and only modify the queue when that is the case,
double newValue = vp.nextValue();
// Check if we have to put the new value in the queue
// that is the case when the queue is not yet full, or the smallest
// stored value is smaller than the new
if (pq.size() < topSize || pq.peek() < newValue) {
// remove the smallest value from the queue only if it is full
if (pq.size() == topSize()) {
pq.poll();
}
pq.add(newValue);
}
This way is potentially more efficient, since adding a value to the queue and removing the smallest are both O(log size) operations, while comparing to the smallest stored value is O(1). So if there are many values smaller than the n largest seen before, the second way saves some work.
If performance is critical, be aware that a PriorityQueue cannot store primitive types like double, so the storing (and retrieving for the average computation) involves boxing (wrapping a double value in a Double object) resp. unboxing (pulling the double value from a Double object), and consequently an indirection from the underlying array of the queue to the actual values. Those costs could be avoided by implementing a heap-based priority queue using a raw double[] yourself. (But that should rarely be necessary, usually, the cost of the boxing and indirections would constitute only a minute part of the overall processing.)
A simple-minded complete working example:
import java.util.PriorityQueue;
/**
* Example class to collect the largest values from a stream and compute their
* average.
*/
public class Average {
// number of values we want to save
private int topSize;
// number of values read so far
private long count = 0;
// priority queue to save the largest topSize values
private PriorityQueue<Double> pq;
// source of read values, could be a file reader, a device reader, or whatever
private ValueProvider vp;
/**
* Construct an <code>Average</code> to sample the largest <code>n</code>
* values from the source.
*
* #param tops Number of values to save for averaging.
* #param v Source of the values to sample.
*
* #throws IllegalArgumentException when the specified number of values is less than one.
*/
public Average(int tops, ValueProvider v) throws IllegalArgumentException {
if (tops < 1) {
throw new IllegalArgumentException("Can't get average of fewer than one values.");
}
topSize = tops;
vp = v;
// Initialise queue to needed capacity; topSize + 1, since we first add
// and then poll. Thus no resizing should ever be necessary.
pq = new PriorityQueue<Double>(topSize+1);
}
/**
* Compute the average of the values stored in the <code>PriorityQueue<Double></code>
*
* #param prio The queue to average.
* #return the average of the values stored in the queue.
*/
public static double average(PriorityQueue<Double> prio) throws IllegalArgumentException {
if (prio == null || prio.size() == 0) {
throw new IllegalArgumentException("Priority queue argument is null or empty.");
}
double sum = 0;
for(Double d : prio) {
sum += d;
}
return sum/prio.size();
}
/**
* Reads values from the provider until exhausted, reporting the average
* of the largest <code>topSize</code> values read so far from time to time
* and when the source is exhausted.
*/
public void collectAverage() {
while(vp.hasNext()) {
// read the next value and add it to the queue
pq.add(vp.nextValue());
++count;
// If the queue was already full, we now have
// topSize + 1 values in it, so we remove the smallest.
// That is, conveniently, what the default PriorityQueue<Double>
// gives us. If we wanted for example the smallest, we'd need
// to use a PriorityQueue with a custom Comparator (or negate
// the values).
if (pq.size() > topSize) {
pq.poll();
}
// Occasionally report the running average of the largest topSize
// values read so far. This may not be desired.
if (count % (topSize*25) == 0 || count < 11) {
System.out.printf("Average of top %d values after collecting %d is %f\n",
pq.size(), count, average(pq));
}
}
// Report final average. Returning the average would be a natural choice too.
System.out.printf("Average of top %d values of %d total is %f\n",
pq.size(), count, average(pq));
}
public static void main(String[] args) {
Average a = new Average(100, new SimpleProvider(123456));
a.collectAverage();
}
}
using the interface
/**
* Interface for a source of <code>double</code>s.
*/
public interface ValueProvider {
/**
* Gets the next value from the source.
*
* #return The next value if there is one.
* #throws RuntimeException if the source is exhausted.
*/
public double nextValue() throws RuntimeException;
/**
* Checks whether the source has more values to deliver.
*
* #return whether there is at least one more value to be obtained from the source.
*/
public boolean hasNext();
}
and implementing class
/**
* Simple provider of a stream of <code>double</code>s.
*/
public class SimpleProvider implements ValueProvider {
// State determining which value to return next.
private long state = 0;
// Last allowed state.
private final long end;
/**
* Construct a provider of <code>e</code> values.
*
* #param e the number of values to yield.
*/
public SimpleProvider(long e) {
end = e > 0 ? e : 0;
}
/**
* Default constructor to provide 10000 values.
*/
public SimpleProvider() {
this(10000);
}
public double nextValue() {
++state;
return Math.log(state)*Math.sin(state) + Math.cos(state/2.0);
}
public boolean hasNext() {
return state < end;
}
}
This is more of a generic question which has to do with static variables and the process life cycle.
I have developed a heavy multi threaded signal processing Android app. It is targeted at API level 9 and above, and if I can it will restricted to only dual core devices. This is purely an academic App and not intended for the general user, and has been developed for teaching Digital Signal Processing. So for this reason I am calculating the DFT many times and so forth so there is quite a bit of computation and size allocation required.
I have declared a bunch of static float and double arrays which get used in static functions like in the example below. The complete code is is a bit to big to put here, so the example below just illustrates the idea.
public class SpecMod {
//Example of global static declarations
static double [][] spectrum = null;
static double [][] phaseMat = null;
static float [][] mframes = null;
static float [][] sframes = null;
static double [] mag = null;
static double [] Pxx = null;
static double [] GAMk = null;
static int nfft = 512;
static float nsegs = 560;
//Compute FFT data
public static void calcSpec(int fs, float [] buffer, float f, float g){
//Example of static array memory allocation
sframes = new float[nlen][(int) nsegs];
spectrum = new double[nfft][(int) nsegs];
phaseMat = new double[nfft][(int) nsegs];
mframes = new float[nlen][(int) nsegs];
mag = new double[nfft];
Pxx = new double[nfft];
GAMk = new double[nfft];
}
public static void fillArrays(){
//Example of array manipulation
for (int j = 0; j < nsegs; j++) {
for (int i = 0; i < nfft; i++) {
mag[i] = spectrum[i][j];
phase[i] = phaseMat[i][j];
Pxx[i] = Math.pow(Math.abs(mag[i]), 2);
GAMk[i] = (Pxx[i] / muPnn[i]);
}
}
}
}
The application is working great as it is. The problem lies in different execution times when say the function fillArrays() gets called. The first time the function is called it takes only 4 seconds to complete, however the second and each subsequent time it is run it takes closer to 30 seconds to complete. In log cat you can see that the heap size does increase drastically the second time, but every subsequent time it stays about the same. In MAT the two dimensional array 'spectrum' retains a large portion of heap. This is understandable as it would contain nfft*nsegs (512*560) sized data stored as doubles.
So I am not sure if the time taken is due to the Garbage collector or perhaps the interpreter going into each step of the for loops (strange tho if the first execution is still short). I thought maybe for all other arrays, setting them to non-static weakreferences so the garbage collector can clean them up, but it seems everything I try is to the same time effects.
So the question is, when using large array objects what is the most effective way to allocate space for them. At the moment they are static, but are not final as the size changes frequently due to user preference. Any help would be great thanks.
Note this is just example code, calcSpec() gets called each time the user changes parameters or a new audio file is loaded to compute frequency data 'spectrum', then only after calcSpec is called, the user can call fillArrays(). In terms of profiling, I have been using MemoryAnalyzer and allocation tracker. The odd thing here the time increase is only in fillArrays(). The first execution it take 4seconds, the second (without calling calcSpec() again, so the same spectrum data is used again) it takes 30 seconds. In both Mat and allocation tracker the Retained size and allocation size are the same for every execution.