- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
the real what the fuck is that you have an explicit number of parameters, and then the implemention looks to be extensible to an arbitrary number of elements. if you really want to do that, then place all the parameters in an array, and pass the array.
maxval = max(a,b) maxval = max(maxval, c) maxval = max(maxval, d) return maxval
but hey, i'm just a simpleton. (and a fiery advocate of the KISS principle)
Admin
When someone computes the max (or min) and initializes with the 0 element, but then starts the loop also at 0, you know they don't really understand how it works. We're in copy-and-paste-until-it-works land, baby.
Admin
Did anyone notice that the final loops starts at 0 although the gtval ist alreday initialized with the first value from the array. for (i=1 .... would have done just as well.
Admin
Actually, we start by setting i to 0, which we then set to 0.
Admin
arrr[] = {a,b,c,d};
Or not?
Admin
The optimal way to implement a Max() function with n arguments is n comparisons. Your approach requires actually n * (n - 1) comparisons or in other words On vs On(n-1). A good example for a worst case argument set would be all arguments being zero.
To implement a proper Max() function you only have the option to nest the conditions like this:
Admin
That reminds me, wasn't there some old Javazone conference teaser video that parodied The Shining, where the Java developer, furious at the bad code, went completely berserk?
Admin
return Math.max(Math.max(a, b), Math.max(c, d));
Fixed?
Admin
That's bad, method overhead. Calling methods is actually slower than conditions because in Java inlining is not guaranteed, in fact a lot of runtimes one various platforms are interpreters, so it's even worse there.
Admin
The optimal way for the max/min of n values i n-1 comparisons, not n
Admin
The code may work, but clearly, any programmer who writes code like this is likely to be even worse at everything else they wrote, including things that are actually important.
Admin
I find it fascinating that, no matter how bad the code is (and I agree with Remy's assessment), commenters here will find ways to make it worse, whether by making it actually slower (thanks for pointing this out), or actually wrong (your own code which returns comparison results rather than values). No wonder people are afraid to refactor the tiniest bits of bad code ...
Admin
Yes, you are correct, it's On-1. Wrote the right implementation counted values but conditions.
Admin
@MaxiTB you shouldn't return the conditions themselves from a Max() function.
Admin
Ha, you are right, I forgot final condition (writing this blindly on a mobile which is a pain). Lemme fix it for ya:
Admin
Yeah, I expected people pointing out that I on purpose ignored NaNs but that's because I don't know how in Java those are handled. There is some weird standard/non-standard (script/non-strict) variants available.
Also I have no idea how the Java profilers all handle scoped versus unscoped conditions (so if vs ?:), but that's up for Java people to point out. I couldn't find anything about that easily, after all Java is a non-standadized proprietary close-source product owned by arguably the worst company in the IT sector.
Admin
Alternative version:
on the basis that if we didn't return a in the first line, there's no point in looking at it again in the others because a isn't the single biggest (it might be joint biggest, but in such a case, it's still legitimate to continue ignoring it). In the same way, after finding that b isn't the single biggest, we can ignore it when looking at c.
Admin
Your code requires 6 conditional checks for a = b = c = d = 0 ;-) That is basically what I was trying to explain in my first post.
Addendum 2024-08-22 10:09: Nvm, brain fart. No idea why I mixed up && and || - guess it's time for me to become a manager.
Admin
How do you get to 6 condition checks? if a is equal to b, a > c and a > d on the first line won't be evaluated, so that's 1 for the first line if b is equal to c, b > d won't be evaluated, so that brings the total to 2 after the second line Which brings the total number of conditions that gets evaluated in that case to 3.
Admin
Because of lazy evaluation that's not actually the case there, A > B would be false so it'll never evaluate the other checks in the first if statement.
Now if we happened to pass in
3, 2, 1, 4
it'd do 6 comparisons to just return the last value, this is because the A>B and A>C checks are both true.Admin
When I saw the array, I was afraid it was going to do a bubble sort to find the largest value. Or, worse, a quicksort.
Admin
I surprised no one offered a single expression composed only of ternary operations, replacing one WTF with another WTF...
Admin
Zeroing of the array speaks volumes. I know a few people who "learned" one language in college and then went to work and had problems because the had to code in a different language. And this code is pre-StackOverflow so give a requirement like "take the max from an arbitrary number of float parameters" to an inexperienced dev and there's a fair chance you'll get exactly that.
Admin
Ternary orperator is unscoped compared to ifs, which means it is an easier optimization target. That's the reason why a lot languages use it to implement their Max() function especially when they allow for inlining (https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5ac14/src/libraries/System.Private.CoreLib/src/System/Math.cs#L910C13-L910C49). But it's good to know that the whole myth that if and ?: are the same still is around.
Admin
Since you asked, I'll take a crack at it...what language is this again?
return (a > b && a > c && a > d) ? a : ((b > c && b > d) ? b : ((c > d) ? c : d));
For extra credit, are the parentheses right? Are they necessary? Do they even balance? Are your eyes bleeding too much to tell?
Admin
No. No. FileNotFound. No.
a > b && a > c && a > d ? a : (b > c && b > d ? b : (c > d ? c : d));
In every language I known that supports the tertiary operator it has pretty much the lowest priority.Addendum 2024-08-22 10:59: C/C++: https://en.cppreference.com/w/c/language/operator_precedence C#: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/
Java is not standardized so feel free to use as many parentheses as you like.
Admin
Except when someone wants to do the same thing in PHP, where ternaries are left-associative instead of right-associative (ref: eev.ee's rant about PHP https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/ ) and it's necessary to put the parens around each ternary to make the whole thing behave.
Admin
It thinks CalculateMaximumValue(-1, -2, -3, -4) == 0.
Admin
Haha, yeah, PHP is extra special - it totally forgot about that one because I haven't done anything in PHP in years now.
Admin
Can you quantify the nanoseconds saved by using
Math.max()
? Unless you are calling this function 100,000 times a second, I wouldn't GAF about method overhead.Addendum 2024-08-22 13:20: Saved by not using
Math.max()
Admin
Wouldn't "return a > d;" return a bool, not the larger of a or d?
Admin
If performance is so critical that you can't afford to use method calls and have to manually inline Math.max(), why would the code be written in Java in the first place? Something like C++ would be more performant, and would be easier to read than those messes of nested ifs that you keep posting too.
Since this is Java code, I have to assume that performance is in fact, not critical. Readability and maintainability are more important, which means something using Math.max() is vastly superior.
Admin
Maia has the best solution.
To anyone who thinks he wants to outsmart javac and jvm have a look at https://medium.com/ayte-io/make-it-visible-a01-javas-math-max-f378c007e419.
JVMs are cleverer than you think. Modern CPUs are cleverer in instruction sets and even branch prediction than you think.
Don't optimise if you don't have a problem with naive solutions. Chances are that you are making things worse not better.
Admin
ITYM "don't optimise unless you know that you have a problem".
Admin
Meanwhile, those of us who use Python are left wondering why a max() function would only support two scalar arguments.
Admin
Why not simply return max(max(a,b),max(c,d)) , Imho that's quite readable and runtime is same for all cases (sometimes matter, don't know about this case, it looks like nothing matters)
Admin
return maxval(maxval(a,b), maxval(c,d));
Admin
Tell me you’re not a Java developer without telling me you’re not a Java developer… although, to be fair, in one of your earlier comments you did in fact reveal that you are not a Java developer…
Java is fully open source. I don’t know why you think it’s closed source and proprietary… either you’re thinking of C# (I’m not a C# developer!), or you’re going back more than 10 years to Java 1.6 or earlier. It’s been VERY open source for at least the last 6 years.
Java is VERY standardised. That’s what allows so many big players (IBM, JetBrains, OpenJDK and others) to create their own versions of the JDK which are guaranteed to be compatible.
No Java Runtimes are purely “interpreters” as you suggest either - Java source code is compiled to Java Byte code, which is then run by the various platform runtimes. Sure, some platforms do some in-line compilation to native code (e.g. HotSpot) - but all Java code is handled by the Java compiler before being executed, so there is always the opportunity for compiler optimisation.
The only statement you’ve made about Java in these comments that I think is factually correct is that it’s owned by one of the worst companies in the IT industry… the rest, it feels like you might be thinking of JavaScript!
Admin
Only at Pirate Software is
arrr[]
(with three 'r' characters in the name) a valid identifierAdmin
Depends on what you mean by "standardised"... It's common for that word to mean "governed by a standard published by a standards body" (meaning e.g. ECMA, ISO/IEC, IEEE, ANSI), and in that definition of "standardised", Java is most definitely NOT standardised.
Admin
how about
float res1 = a > b ? a : b; float res2 = c > d ? c : d; return res1 > res2 ? res1 : res2;
3 lines, 3 comparisons.
Addendum 2024-08-23 05:40: well, it would be three lines if i could work out how the formatting worked
Admin
Well, the code is clear and simpler, so before super-optimizing it, you should be sure that there is actually a need for performance, and then that the code is not already running on a modern Java VM with hotspot jit.
Admin
Three backticks on a line by themselves before the code, and three more on a line by themselves after the code.
Admin
Addendum 2024-08-23 10:53: Screwed up the formatting, so I reposted it below.
Admin
Not compiled, translated. Compilation (like C/C++/.net) is the process of turning source code or an intermediate code into machine code which is then in return executed. Interpretation (BASIC/most Java versions) interprets intermediate code and executes functions based on those parameters of the interpreter. In other words compilers compile everything into machine language once, interpreters translate every intermediate instruction over and over again. Hot-spot compilation is caching the execution path if similar executions are repeatingly executed and skipping the interpretation part (which is often more extensive than the execution itself). Sun introduced this feature after getting smoked performance wise by compilers and it greatly improved performance hence modern Java is only half as slow compared to an equal C# application. Finally there's native generation which basically means to generate all or some native code and embbed it into your package. As a compiler framework .net had that from the start, don't know if it's a thing in Java yet, last time I check the best that was available was complete ahead of time compilation which generates a complete native application only.
I honestly have no idea what you are talking about. A runtime is a low level construct of basic language features (like how to handle basic types like unsigned integers, manage memory, how vtables are build up), it's the code and interpreter calls based on intermediate code and a compiler translates into calls which depending on the call conventions are either have the arguments push on the stack, directly using registers or a combination of both. In other words it's a library not a program, it doesn't run, it is called at runtime, hence the name.
Admin
Javascipt is a standardized language from Netscape and has nothing to do with Java. At all. Naming it like that was a marketing idea because back then 90s only a few people mostly in academic circles and professional developers knew that Java was the left-over of a cancelled OS which they themselves marketed as this brand new idea and business hyped it to insane levels. Netscape decide to ride the hype train and so the name Javascript was born.
Admin
And the first part again, because it got mangled.
No it's not, OpenJDK is a fork and has heavy restrictions place upon it after Oracle sued the organization (those are called classpass exception - https://openjdk.org/legal/gplv2+ce.html). It's a mixture of open source and proprietary code. Besides, only the JDK is partially open source, everything else ("VM", runtime, compiler, profiler etc. is completely close source and proprietary. Again Oracle sued multiple companies over this in the past.
This nonsense again. The Mono project was around since .net Framework 1.1 and indirectly supported by MS (they could do it directly because of their internal policies) and Mono is around to these days, it's basically on every mobile phone. .net core went full open source (MIT/Apache 2/CCA4) including compilers, tooling, everything complete and for all platforms (https://dotnet.microsoft.com/en-us/platform/open-source).
Twitter is not a standard as it not any page because it's on the net. Standardized means you are standardized following an international/nation standards organization like ECMA, ISO/IEC, IEEE. Pretty much every language on this plat is standardized, they tried to do the same for Java, but it was already in the early 2000s such a mess, it was impossible to do so without inventing basically a new language that would have broken every existing Java code. So no Java is not standardized and will most likely never be; Sun tried to get that done for years and failed. On the other hand the .net framework (both CLS/CTS) is fully ISO standardized (which is the basis for netcore as well) and various versions of .net languages are standardized themselves like C#.
Admin
Okay, by your very narrow definitions of “compiled” and “standardised”, Java is neither compiled nor standardised.
From a slightly more pragmatic view point, it is compiled - you convert source code into byte code using a compiler, which is then executed on a virtual machine. Sure, it’s not compiled all the way to native executable code - but nor is it interpreted directly from source code.
Sure, Java doesn’t follow a standard created by an external third party… but it is standardised, and there are documented behaviours. You argued that you couldn’t comment on how Java would handle the scoping of if vs. Ternary because Java isn’t standardised… that’s just throwing shade.
Admin
It's not compiled to native code by javac. That's left to the JIT... for code that really needs that. All implementations of note use a JIT.
Admin
Ok, let's never call methods in Java then, because of the overhead. As a human who has to read and maintain code, I would prefer the readable Math.max solution over some nested conditions (which are still readable, albeit a little less so than the former solution). If profiling reveals that I'm wasting CPU cycles calling a method, then I'll refactor it. That's honestly never been a significant performance bottleneck in anything I've worked on and I don't know why people feel the need to point out the overhead of a function call when it's entirely insignificant 99.999% of the time. Just build the thing, then go through it with profiling tools and make it faster.