So, my question would be.... What is the most efficient way to do this type of operation? This code is meant to be executed many (as in once per pixel at least) times per frame. Is there some bit-shifting trickery that could be used? Some arithmetic magic?

Currently, my generalized (using doubles as the value type) implementation is as follows:

Also, encapsulate the code into a class and pre-calculate the 'fixed' stuff as class members, i.e. work out the range, step and scale values once in the constructor to avoid having to calculate them on every call of the filter() method.

@StrideColossus: What is the purpose of the scale variable in your formula?...I understood your problem to be how to determine if a value should be a part of set #1 or set #2, #3... so on and so forth, so I felt like returning an int would suffice.

If you implement the filter method as you suggested (to return 1, 2, 3, etc) then 'scale' is redundant.

I thought the OP was asking for the results to be in the range 0/100/200. You could use your approach (without the +1 at the end) and multiply the result by 100, the results would be the same I think.

Also, encapsulate the code into a class and pre-calculate the 'fixed' stuff as class members.

That is of course how it will end up in the final code. The generic approach I posted is there just to make it easier to understand what the general case of my question would look like (heck, could be generalized more by using a generic variable type).

As for the intervals (slices), no, they don't necessarily have to be of equal size.

This is an (specific, for 4 equal intervals, and a range of 0.0 to 1.0) example of how I am actually using this in my code:

Not to sidetrack the discussion, but I wouldn't necessarily call this filtering. Whenever I have heard the word filter used in programming it has been to drop items from a collection according to some predicate. What you have is more of a map. You have an input set of values that maps to a smaller set of output values.

If you search java map range of values in Google, some interesting things come up. If the number of "buckets" is fairly small and there are no "holes" then the simplest would be to store two arrays. One which has the max range of each bucket, the other which has the output value.

This doesn't take advantage of equally spaced slices but it should be plenty fast. If you have a large number of buckets, it may be worth while doing some sort of binary search type set up to reduce the number of comparisons.

Generally speaking, I'm pretty sure that any conditional statement is going to take a lot longer to evaluate than a series of mathematical ops. So some version of @StrideColossus's code but with the precalculated values seems the best to me.

The one thing I would say is that when dealing with problems of this type, it is best to take another look at whether you actually need it. Sometimes I get so worked up with solving a problem efficiently that I don't realize that I caused it in the first place.

Actually, I had to do something like this when I was coding a game. Though it is not really a filter, but it is more like deciding a certain output when you hit a range of values.

In my case, my range was from 0 - 1000 and my output values I wanted was 100, 200, 400, 800, etc. So, to generate a range, I actually used a one line for loop.

1 2 3 4 5

inti;//The index of the for loopintj;//The values you want to get from a specific rangeintrangeValue;//The value chosen for the rangefor(i = 100, j = 0; i <= rangeValue; i*=2, j++);System.out.println("For "+rangeValue+" : the output is "+j+".");

I did achieve similar results using the modulus operator "%" as well. But, let me take a whack at trying to get your code working efficiently as you would want in the original post.

In this case, the j serves no purpose. But, with a bit of editing, you can have it work as an index number for an array, or anything else that you need to split the ranges up. It is a lot more processing work, but it is more flexible and gives you more control. (If not, there is always using modulus ).

I think the OP doesn't mean Java generic, but 'works for each primitive type'.

Indeed. Just specified that because maybe there are some tricks that only work with specific primitive types, and that's something I want to know.

I'm really liking pitbuller's suggestion, by the way, simple, rather elegant, and only performs a single arithmetic operation. It won't work with differently sized intervals, though, but since the objective is to make an specific implementation for the task, rather than have a generic method, it can be tweaked.

Sorry for being such an overoptimizer tonight but... I'm guessing the compiler is already doing this, but since the value array is static, I could simply inline the array indexing and get rid of the method calling overhead too. Hmmmm.

Sorry for being such an overoptimizer tonight but... I'm guessing the compiler is already doing this, but since the value array is static, I could simply inline the array indexing and get rid of the method calling overhead too. Hmmmm.

Yes, the JIT will do that.

If you *really* want to over-optimise the fully generic case, you should look at a custom class loader which generates a balanced decision tree...

Seriously; this is the very definition of premature optimization. It leads to shitty code and poor programming practices. If you apply this kind of thought to all aspects of your game/software, it will be a bitch to debug later down the line, will take you several times longer to develop, and ultimately will perform no better.

"Method overhead" is extremely negligible. If you benchmark and find that the algorithm needs optimization, it will most likely not do anything to inline your methods except further obfuscate your program.

Are you using OpenGL? Why aren't you using shaders? Are you using PBOs to allow for async transfer of pixel data? etc. These are the optimizations you should be considering. (If you're using Java2D; then maybe you're using the wrong library for the job.)

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org