|
It sure does its job, wich itself is not really complicated. So why don't you just post your more fitting version?
A while ago he asked me what he should have printed on my business cards. I said 'Wizard'.
I read books which nobody else understand. Then I do something which nobody understands. After that the computer does something which nobody understands. When asked, I say things about the results which nobody understand. But everybody expects miracles from me on a regular basis. Looks to me like the classical definition of a wizard.
|
|
|
|
|
I'd probably go for this approach
public boolean displayModesMatch(DisplayMode mode1,
DisplayMode mode2)
{
boolean isEqualDimention = (mode1.getWidth() == mode2.getWidth() && mode1.getHeight() == mode2.getHeight());
boolean isEqualDepth = (mode1.getBitDepth() == mode2.getBitDepth());
boolean isEqualRefreshRate = (mode1.getRefreshRate() == mode2.getRefreshRate());
return (isEqualDimention && isEqualDepth && isEqualRefreshRate);
}
I think this is much more readable and much simpler.
|
|
|
|
|
Nice and well, but what happened to the BIT_DEPTH_MULTI and REFRESH_RATE_UNKNOWN business? Including those two will take away some of the neatness again. And what if we don't just want to check three things? What if there are 20? Then you will have 20 variables which are used in one fat term at the end.
A while ago he asked me what he should have printed on my business cards. I said 'Wizard'.
I read books which nobody else understand. Then I do something which nobody understands. After that the computer does something which nobody understands. When asked, I say things about the results which nobody understand. But everybody expects miracles from me on a regular basis. Looks to me like the classical definition of a wizard.
|
|
|
|
|
I believe BIT_DEPTH_MULTI and REFRESH_RATE_UNKNOWN don't need to be there. they are constants. even if they should be there, it still would be a lot cleaner. I'm not saying this IS the best approach i'm just saying how i think is the cleanest solution.
Even with 50 things to check it's much more readable using variables then doing some if structures :p
|
|
|
|
|
Both may be constants, but they do play an important role here. Your version would wrongly return false in some cases when those two constants appear.
Besides that, your approach works and is neat enough. Unfortunately things are not always as simple as they are here. This can very quickly turn into a bowl of spaghetti and some compromises may have to be made. Unfortunately. Anyway, the original version still is not so bad that it's a horror.
A while ago he asked me what he should have printed on my business cards. I said 'Wizard'.
I read books which nobody else understand. Then I do something which nobody understands. After that the computer does something which nobody understands. When asked, I say things about the results which nobody understand. But everybody expects miracles from me on a regular basis. Looks to me like the classical definition of a wizard.
|
|
|
|
|
lordofawesome wrote: I believe BIT_DEPTH_MULTI and REFRESH_RATE_UNKNOWN don't need to be there.
According to the original function comments, that is incorrect. You can't just change the premise of the code on a whim. You can make it cleaner in any way you feel you want (even though it worked), but you can't change the unit requirements after it has already been in use like that.
lordofawesome wrote: even if they should be there, it still would be a lot cleaner.
Fine, but you must include those constants if they were already there. incorporate them into your code.
lordofawesome wrote: Even with 50 things to check it's much more readable using variables then doing some if structures
Some would agree with you, some would disagree. Let's put it this way: if someone wrote code that works, leave it alone. Why reinvent the wheel?
|
|
|
|
|
Hi,
One reason for the original approach is it reduces processing time, which is of primary importance for a game engine.
Your proposal will require the function to process each variable before returning while the original will check the most likely areas of failure first, then return -- eliminating the need to process the further checks.
|
|
|
|
|
Runtime behavior would be worth a look for any code executed inside the rendering loop. Display modes usually are checked beforehand, so yes, technically this would be faster, but the effect would be unnoticable.
A while ago he asked me what he should have printed on my business cards. I said 'Wizard'.
I read books which nobody else understand. Then I do something which nobody understands. After that the computer does something which nobody understands. When asked, I say things about the results which nobody understand. But everybody expects miracles from me on a regular basis. Looks to me like the classical definition of a wizard.
|
|
|
|
|
Assuming it really is faster, this method isn't really part of the engine itself. it's not like this function will be run over and over again. Me personally, i wouldn't compromise readability over such a small performance increasement.
But i'm severely starting to doubt myself, a lot of people seem to disagree this is a codehorror :s
|
|
|
|
|
Don't fret about posting. Most of the horror posts don't seem to generate this much discussion. I see that as a good thing.
|
|
|
|
|
Ye i like the activity on this forum
|
|
|
|
|
have you ever had time to go get a burger during a loading scene...?
I'd blame it on the Brain farts.. But let's be honest, it really is more like a Methane factory between my ears some days then it is anything else...
-"The conversations he was having with himself were becoming ominous."-.. On the radio...
|
|
|
|
|
.. argh I should have read all the sub threads before posting.. sorry.
I'd blame it on the Brain farts.. But let's be honest, it really is more like a Methane factory between my ears some days then it is anything else...
-"The conversations he was having with himself were becoming ominous."-.. On the radio...
|
|
|
|
|
What you have posted here is exactly what DisplayMode's equals method does, so you could replace the whole lot with:
return mode1.equals(mode2);
You can't get much simpler than that.
But that is not what the original code does. The original code takes BIT_DEPTH_MULTI and REFRESH_RATE_UNKNOWN into account, which your code and the equals method does not.
|
|
|
|
|
But aren't these simply constants? So the value would still have to be the same right? if so, this would mean that you don't need to take them into account. Or am i missing the point :s
|
|
|
|
|
Yes, they are constants, but you do need to take them into account. Consider the following:
if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
mode1.getBitDepth() != mode2.getBitDepth())
This is saying:
- if either mode1 or mode2 has BIT_DEPTH_MULTI then I can ignore the bit depth, and I can consider that these two display modes match no matter what bit depth they have.
- if neither mode1 nor mode2 have BIT_DEPTH_MULTI then I need to check that the bit depth matches.
This is different from the equals method, which says that they are only equal if they both have exactly the same bit depth, whether that is BIT_DEPTH_MULTI or not.
|
|
|
|
|
ty for the clarification it appears that these need to be added to the line also. Though this changes nothing to the structural fail of the code
|
|
|
|
|
not necessarily, you have mip-maping, or dynamic scaling, or in game render target changes...
I'd blame it on the Brain farts.. But let's be honest, it really is more like a Methane factory between my ears some days then it is anything else...
-"The conversations he was having with himself were becoming ominous."-.. On the radio...
|
|
|
|
|
you version here is more costly...
You have to remember that when your doing a game engine each comparison burns cycles, the initial example i would argue is faster to execute, if you know more about your environment...
if the first statement is true, then you cut down on the number of lookups...
using your "better code" actually has worse performance... because you force all the lookups!
I'd blame it on the Brain farts.. But let's be honest, it really is more like a Methane factory between my ears some days then it is anything else...
-"The conversations he was having with himself were becoming ominous."-.. On the radio...
|
|
|
|
|
Check my last reply, 1 statement, no variables, only indenting to preserve readability and my personnal favorite
|
|
|
|
|
I likes it at first glance.... succinct.
These calls in my experience can be a bit black box however and although would work fine in situations where compute time isn't at a premium is always the best way to go, i would (at least in my projects) check to see if it is actually faster and produces less garbage (GC type garbage, not the visual type, which it obviously doesn't...).
it's also been my experience that a lot of these nice API methods are just wrappers for crappy unoptimized code... the XNA. Vector3d.Distance function is a prime example of this... problem with API functions is that they need to be generic, and work in all situations (even when given properties..etc) and as such often make internal scope storage "inside the black box" to accomplish their result...{actually posed this question to a guy who wrote that function on the XNA team.. this was his answer!} so I see it as elegantly coded, but not necessarily the best approach in all situations..
I'd blame it on the Brain farts.. But let's be honest, it really is more like a Methane factory between my ears some days then it is anything else...
-----
"The conversations he was having with himself were becoming ominous."-.. On the radio...
|
|
|
|
|
Your code also checks things it needn't - once the first bool is false we know the displays are not the same so we can short circuit and return - why do the extra compares unless you just want to burn a bit of CPU
|
|
|
|
|
I think the original version is better because I read it once and was reasonably confident I knew what it did, and also what was intended.
The shorter, cleverer version I looked at and said "Eh?".
In my first job I discovered that programs might have to survive being "fixed" by a half-drunk trainee who had been dragged from the pub when something went wrong on Friday night at the start of a holiday weekend and all the sober and competent programmers were gone. I know, I was that trainee.
OK, so this isn't an IBM 360 COBOL accounting program, but still, clarity of intention is desirable.
KISS, in fact.
|
|
|
|
|
This format definitely has an advantage in that if you suspect displayModesMatch of doing something wrong, or otherwise just want to know what it is doing, you only need to set one breakpoint.
I guess both approaches have their merits.
But before we just go ahead and assume that this way is better than that way, let's see how C++ would have done this task. I found the results quite surprising.
To simplify, I used the following code snippet:
bool test1(int dim1, int dim2, int depth1, int depth2, int refresh1, int refresh2)
{
bool isEqDim = (dim1 == dim2);
bool isEqDepth = (depth1 == depth2);
bool isEqRefresh = (refresh1 == refresh2);
return isEqDim && isEqDepth && isEqRefresh;
}
bool test2(int dim1, int dim2, int depth1, int depth2, int refresh1, int refresh2)
{
if (dim1 != dim2)
return false;
if (depth1 != depth2)
return false;
if (refresh1 != refresh2)
return false;
return true;
}
void trialrig()
{
int dim1, dim2, depth1, depth2, refresh1, refresh2;
scanf("%i", &dim1);
scanf("%i", &dim2);
scanf("%i", &depth1);
scanf("%i", &depth2);
scanf("%i", &refresh1);
scanf("%i", &refresh2);
bool b1_1 = test1(dim1, dim2, depth1, depth2, refresh1, refresh2);
bool b2_1 = test2(dim1, dim2, depth1, depth2, refresh1, refresh2);
if (b1_1)
printf("b1 is true\n");
if (b2_1)
printf("b2 is true\n");
}
The scanf's were important, because if they're not there, my compiler just optimized both the test functions out of existence.
During compiling, some of these were inlined, so I have to compensate somewhat. So for simplicity, assume that both code blocks below are prefixed with these instructions:
mov eax, DWORD PTR _dim1$[esp+88]
mov ecx, DWORD PTR _dim2$[esp+88]
mov esi, DWORD PTR _depth1$[esp+88]
mov edi, DWORD PTR _depth2$[esp+88]
mov ebx, DWORD PTR _refresh1$[esp+88]
mov ebp, DWORD PTR _refresh2$[esp+88]
In release build, it produced the following for one of the two functions (excluding the preamble above):
cmp eax, ecx
jne SHORT $LN7@test12
cmp esi, edi
jne SHORT $LN7@test12
cmp ebx, ebp
jne SHORT $LN7@test12
mov dl, 1
jmp SHORT $LN8@test12
$LN7@test12:
xor dl, dl
$LN8@test12:
And the following code for the other function:
cmp eax, ecx
je SHORT $LN11@test12
xor bl, bl
jmp SHORT $LN9@test12
$LN11@test12:
cmp esi, edi
je SHORT $LN10@test12
xor bl, bl
jmp SHORT $LN9@test12
$LN10@test12:
cmp ebx, ebp
sete dl
$LN9@test12:
Now just to drive the point home, I'm not going to tell you which of those two code blocks were produced by which function, because as you can see, they're quite similar.
Now, for the first snippet, starting at the cmp, the longest path of execution is 8 instructions, and the shortest path of execution is 3 instructions. For the second snippet, the longest path of execution is 6 instructions, and the shortest path is 4 instructions.
So to summarize, one approach takes 3-8 instructions, whereas the other takes 4-6 instructions.
So if this code was in a real tight loop somewhere, which approach is actually faster depends really on what you expect the outcome to be.
Never assume that you know how the compiler/bytecode interpreter is going to optimize things, and never optimize things without profiling your code to see where the real bottle necks lie.
|
|
|
|
|
Wow this information is interesting. Thx for the effort. I could be wrong but i can't see the solution with 1 statement anywhere among your tests functions. I presume that using that solution would be even faster.
|
|
|
|
|