The best way to handle options in a performance-based application - performance

The Problem
I'm writing an application where performance is very important. (Specifically: A raytracer)
I want to have an option for something called "Adaptive Supersampling" in my program. It's fairly simple to implement but I want to have an option to turn it on or off.
Unfortunately I only see two options, which are:
Put an if/else around two separate procedures (which are fairly similar) like so:
void renderLoop() {
if(adaptive) {
doAdaptiveLoop();
} else {
doNormalLoop();
}
}
Put specialized if/else statement scattered around the code.
void renderLoop() {
if(adaptive) something();
else somethingElse();
for(int i = 0; i < LOOP_1; i++) {
if(adaptive) something1();
else somethingElse1();
for(int j = 0; j < LOOP_2, j++) {
if(adaptive) something2();
else somethingElse2();
}
}
//... So on and so forth
}
Both of these methods are fairly terrible. Method 1 repeats a lot of code, and Method 2 is both messy and inefficient. Both of them make it very difficult to add on many features. If I want to add more features, I have to add more if/else statements at a factorial rate with Method 1, and in a very confusing way in Method 2.
The Question
I've run across this problem many times in performance dependent applications, but I've never really been able to solve it.
The questions is: How do I add toggleable features to my program which is centered around many loops, whose performance will decrease with many boolean tests, and whose code will become messy with those tests?

I also run into this problem on a regular basis, and I usually have to choose between options 1 and 2. If the number of options keeps growing, I usually fall back on the swiss-army-knife method: code generation.
In other words, I write program A to write functions B1, B2, etc. Program A takes the options as arguments and generates the appropriate function Bi as a text file, and then the final program includes all the Bi.
It's not pretty, but pretty is overrated.
The advantage is, the common code among all the Bi is only stated in one place, so if you make a change to it, you only have to do it in one place, so you have fewer opportunities to get it wrong.

I think what you are searching for are function pointers or the analogous.
Let me elaborate, you specifically asked for performance, and I agree that chasing pointers might get in your way - BUT since you now seem to have a large number of branches depending on settings somewhere inside you application, you might as well wrap that code up in some function pointers. That does not mean you should call a function through a pointer when just adding two vectors.
On a side note; this is also relevant when parallelizing code; the work-items need not be too large as to mitigate the parallelization efforts but need be large enough to be processed efficiently.

Maybe use a global function pointer variable to hold the loop function your options tell you to use.

Related

Is it better to give a function an additional parameter, or to make the parameter static?

Many times I've come across a situation where I am calling a method many times with one parameter always exactly the same, and I need to add some additional parameter defined in my main method. I'm never sure what to do about the additional parameter. It seems like it might be a better idea to make the parameter static to make the code cleaner, but then, static variables are not very good. Still, adding parameters can in some cases lead to very long lists of parameters that are in a way unnecessary, and I imagine that there will be a speed disadvantage as well when your function is short, called often, and has a lot of parameters.
Here's the most recent code (kotlin) that has had me thinking about this problem, but I've ran into the problem a lot in different languages.
tailrec fun getAncestor(ind: Int, parent: IntArray): Int {
if (parent[ind] == ind) return ind else return getAncestor(parent[ind], parent);
}
Is it better to make parent a static variable and not have it as a parameter to the method? (Assume that every time that this method is called, the second parameter will be the same. I'm usually only writing short 100 line code files for competitive programming so there is no chance the method will be reused with a different second parameter)
In general if you're working on a project, you'll want to stay away from static variables because when the project starts scaling up and getting bigger, it'll be very hard to keep track of the static variables and this will make it very hard to debug.
In competitive programming, I suggest go for the quicker approach.
In my opinion, it depends on your preferred coding paradigm. For instance, if you'd like your code to conform to the functional paradigm, your code is fine how it is now (regarding the parameter), however, if you don't care about the functional programming, having that param extracted out, as a constant is alright. I see no reason why it should be bad. If you worry about the performance, you could declare it as lazy, but otherwise it'd fine, I guess.

Cleaning Functions containing if statements

I hope that this is the right place to ask (if not please tell me). I am currently trying to create a game while following Robert C. Martins book "Clean Code" in an effort to improve the readability of my code. I am not totally happy with how many of my functions work however, as more often than not I will need to check various variables before I execute a command. For example:
private void checkScoreAndIncreaseDifficulty() {
if(eater.getScore()%400==0){
world.increaseDifficulty();
}
According to the book I am following functions should only do one thing, but when an "if" statement is involved the functions purpose (to me) seems to naturally increase. The name of the above function is checkScoreAndIncreaseDifficulty which is quite clearly two things but I cannot think of how to reduce it. I feel the solution is very simple but it just is not coming to me. Any advice would be appreciated.
Names of functions are supposed to describe what the function does,not how achieves something. So naming checkScoreAndIncreaseDifficulty is wrong imo. It should be something similar to IncreaseDifficulty. Moreover if you do not feel that names of your code elements do not give enough insight on what the function / class/ variable does, you can always comment your code. :)
Also, the "correct" place to write your conditional statement depends entirely on your application : if difficulty will increase only if the user satisfies some condition, then that condition should be included in the function that increases difficulty. If the difficulty might be increased by other means, then the function should only execute actions that increase difficulty and leave the decision whether to increase difficulty or not to the caller.
I don't see any way to make this method cleaner than it is. It checks the score, and then hands of the increaseDifficulty to another method. What more can you ask?
I think there's also a risk in trying to make methods as minimal as they can possibly be. At some point, you need to dig through a dozen methods and functions spread through your entire codebase in order to understand what a single method or function does. That's no good either.
As far as I'm concerned, your code hits the sweet spot. The cumbersome name is indeed an issue, but not a serious one, and easy enough to fix, if you really want to.
Why don't you use two separate functions(you can do it also with only first function) like this:
private bool isScoreEnough() {
if(eater.getScore()%400==0)
return true;
}
private void increaseDifficulty(){
world.increaseDifficulty();
}
and in your program:
if(isScoreEnough())
increaseDifficulty();
You are setting difficulty level in the function. Depending on score you increase/decrease the difficulty level. That is perfectly fine - as long as the function does the job of determining and setting difficulty level only. Function name has scope for improvement:
private void setDifficultyLevel() {
if (eater.getScore()%400 == 0) {
world.increaseDifficulty();
}
}
Obviously you won't find much code without any if statement, programs have to make decisions based on state, input or whatever. Avoiding if statements at all is also not the key message of "Clean Code". What you should avoid are for example endless if-else constructs if one class does the work of three logical cases - you should have three classes then.
Your method is already pretty short, but if you want to apply one of Martin's principles (a good name spares comments etc.) even further you could use something like:
if (scoreRequiresIncreaseInDifficulty()) {
increaseDifficulaty();
}
and then implement the two methods. However, I don't think this makes much sense in your case unless you will need the same calls multiple times and want to maintain the flexibility to change when the score requires a more difficult game in a single place.
You want to increase difficulty every 400 score points gathered by the eater, right?
So, you would need the eater to allow subscribing for score changes:
interface Eater {
void addScoreChangedListener(ScoreChangedListener listener);
}
interface ScoreChangedListener {
public void onScoreChanged(Score previousScore, Score newScore);
}
The implementation of Eater would hold a list of all score change listeners and invoke the onScoreChanged on each of them when the score changes. See the Observer pattern.
And then when bootstrapping your game:
Eater eater = ....
eater.addScorechangedListener(new DifficultyAdjustScoreChangeListener());
And you are done!
The implementation of DifficultyAdjustScoreChangeListener need to have the if, though, but that's ok:
class DifficultyAdjustScoreChangeListener implements ScoreChangedListener {
public void onScoreChanged(Score previousScore, Score newScore) {
if (newScore.value() % 400 == 0) {
world.increaseDifficulty();
}
}
}

Should conditional wrap call or code?

Currently trying to refactor some legacy code and I find myself stumbling across the same situation over and over again. I have a very large function that I want to use extract method on for several blocks. Many times the blocks I aim to extract are wrapped entirely in a conditional. From a style / best practice standpoint, does it make sense to leave the conditional wrapping the new method call, or extract the conditional wrapping code into the new method. Can you explain the pros / cons?
i.e. do you prefer
A)
Big_function() {
<...>
If (conditional) {
Small_function();
}
<...>
}
Small_function() {
Code
}
Or B)
Big_function() {
<...>
Small_function();
<...>
}
Small function() {
If (conditional) {
Code
}
}
Maybe this is trivial, but since I see it a lot, thought I would ask. Let's assume small_function would not be reused in either form, simply used to extract this block.
thanks.
It depends on the context. For each instance, if you have a gut feeling either way, you're probably right. Just make sure the name of the inner function matches the implied if check, or lack of thereof.
With that concern out of the way, the best thing to do is to put the if inside the inner function, because there is one big complicated outer function and many simple inner functions. One extra if check inside several small functions will not add much complexity to them individually, whereas adding lots of extra branches into the outer function will meaningfully affect its complexity and readability.
Lastly, there is a slight perf tradeoff to putting the check inside the inner function vs outside. You can sometimes incur additional costs of calling and returning from the inner function when the if evaluates to false, but on the other hand your outer code can be slightly smaller (fewer instructions). For this to make any meaningful impact either way, the outer function has to be VERY hot, and you have to be writing in a low-level language.

What the ugliest API for a relatively well known library that you have seen, and why and how could it be improved? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have been looking at the differences between Lucene 2.9 particular the redone tokenstream API and it just occurs to me its particularly ugly compared to the old just return a new or repopulate the given with values if your reusing said Token.
I have not done any profiling but it seems using a MAP to store attributes is not that efficient and it would be easier to just create a new value type holding values etc. The TokenStream and Attribute stuff looks like object pooling which is pretty much never necessary these days for simple value types like a Token of text.
creat()
When Ken Thompson and Dennis Ritchie received the 1983 Turing Award, after their respective acceptance speeches, someone in the audience asked Ken what he would do differently with Unix if he were to do it all over again. He said, "I'd spell 'creat' with an 'e'."
Livelink (OpenText) API
Everything comes back as some bizarre form of a jagged array
The documentation provides absolutely no examples
[your favorite search engine] typically returns no results for a given API method
The support forums feel near abandoned
The only reliable way of understanding the resultant data is to run the data in the Livelink debugger
And finally... the system costs tens (hundreds) of thousands of dollars
The wall next to my desk has an imprint of my head...
A very simple example of getting a value out of an API method:
var workflow = new LAPI_Workflow(CurrentSession);
// every Livelink method uses an out variable
LLValue outValue;
// every method returns an integer that says if the call was
// a success or not, where 0 = success and any other integer
// is a failure... oh yeah, there is no reference to what any
// of the failure values mean, you have to create your own
// error dictionary.
int result = workflow.ListWorkTasks(workId, subWorkId, taskId, outValue);
if (result = 0)
{
// and now let's traverse through at least 3 different arrays!
string taskName = outValue.toValue(0).toValue("TASKS").toValue(0).toString("TaskName");
}
Aaack!!! :D
I've never been a fan of the java.sql package...
You have to catch the checked exception for everything, and there's only one exception, so it doesn't really give any indication of what went wrong without examining the SQL code String.
Add to that the fact that you have to use java.sql.Date instead of java.util.Data, so you always have to specify the full package for one or the other. Not to mention the conversion that has to take place between the two.
And then there's the parameter index, which is 1-base-indexed instead of the rest of Java, which is 0-base-indexed.
All in all, a pretty annoying library. Thankfully, the Spring library does make it quite a bit easier to work with.
COM. Its biggest improvements ended up being .NET.
Certain java.io.File methods, critical to systems programming, return a boolean to indicate success or failure. If such a method (like, say, mkdir or delete) fails, you have no way at all to find out why.
This always leaves my jaw a-hangin' open.
Java's date/time API is pretty horrible to work with. java.util.Date has several constructors to create an instance for a specific date, but all of them are deprecated. java.util.GregorianCalendar should be used instead, but that has an extremely annoying way of setting fields (think calendar.setField(GregorianCalendar.MONTH, 7) instead of calendar.setMonth(7) which would be far better). The finishing touch is that most other classes and libraries still expect a Date instead of a Calendar, so you have to constantly convert back and forth.
Not not a winner, but deserves a honourably mention; Android. Uses the Java 5 programming language, but barely any of the Java 5 language features. Instead of enums you get integer constants with prefix or suffix.
It can not quite decide if it should be object oriented, or procedural. Showing dialogs being a prime example. Several callbacks with self defined integer ids to display call upon the dialog, that smells of an old C API. And then you get an inner builder class class with chained methods, that smells of over architectured OOP of the worst kind.
The MotionEvent class have X and Y coordinates as absolute and relative values from the same accessory method. But no way to check what kind of coordinates it currently holds.
Android sure is a mixed bag.
I'm going to turn this question on its head and name a beautiful API for a library whose standard API is mostly ugly: the Haskell bindings for OpenGL.
These are the reasons:
Instead of lumping everything into a small number of headers, the library is organized logically into discrete modules, whose contents parallel the structure of the OpenGL specification. This makes browsing the documentation a pleasant experience.
Pairs of "begin/end" functions are replaced by higher-order procedures. For example, instead of
pushMatrix();
doSomeStuff();
doSomeMoreStuff();
popMatrix();
you'd say
preservingMatrix $ do
doSomeStuff
doSomeMoreStuff
The syntax of the bindings enforces the conventions of the library, instead of making you do it by hand. This works for the drawing primitives of quads, triangles, lines, etc. as well. All of this is exception-safe, of course.
Getters and setters are replaced by idiomatic "StateVars", making reading and writing a more symmetric operation.
Multiple versions of functions replaced by polymorphism and extra datatypes. Instead of calling, say, glVertex2f with two float values, you call vertex with a value of type Vertex2 GLFloat.
References:
API Reference
The HaskellWiki page on OpenGL
Beautiful Code, Compelling Evidence (pdf)
Praise from Scott Dillard, quoted in Beautiful Code, Compelling Evidence
Direct3D!
No doubt the old pre-Direct3D 5 interface was pretty darn fugly:
// GL code
glBegin (GL_TRIANGLES);
glVertex (0,0,0);
glVertex (1,1,0);
glVertex (2,0,0);
glEnd ();
// D3D code, tonnes of crap removed
v = &buffer.vertexes[0];
v->x = 0; v->y = 0; v->z = 0;
v++;
v->x = 1; v->y = 1; v->z = 0;
v++;
v->x = 2; v->y = 0; v->z = 0;
c = &buffer.commands;
c->operation = DRAW_TRIANGLE;
c->vertexes[0] = 0;
c->vertexes[1] = 1;
c->vertexes[2] = 2;
IssueExecuteBuffer (buffer);
Its not too bad, nowadays - it only took Microsoft 10 versions to get it right...
I would say MFC, ATL and WTL. All 3 of these libraries use excessive hungarian notation, redefine data types for no apparent reason (CString redefined over and over) and are notoriously changed with each version of visual studio.
I like COM. It provides a component oriented architecture long before .NET was even developed. However, the expansion of COM into DCOM, its many wrappers like ATL and its general lack of comprehensive documentation make it the ugliest API i have to deal with at work.
Most certainly not the ugliest. There are probably so many, but Flex has a special place in hell. Specifically UIComponent which compared to the Sprite, feels like using a chainsaw to peel an apple. I believe Flex would have been much improved by using more lightweight objects and mixin-style features similar to how Dojo works on the Javascript side.
The ECMAScript/Actionscript Date class is all but backwards and useless. It's been a constant pain any time I've needed to do something more complex than add timestamps to logs. They need more parsing options (e.g., the ability to specify the input format), and better time management, like intelligent increments, convenience functions, etc...
C++ STL libraries (and templates in general), while obviously useful, have always felt plain ugly. No suggestions for improvements though. They work.
Oracle's ProC, ProAda, Pro*this-that-the-other things. They were a preprocessor front end for C, Ada, and Fortran, I think, maybe some others, that let you jam SQL into your source code.
They did also have a library which worked much better, and was much more flexible.
(That was more than 10 years ago, I have no idea what they do now, though I wouldn't be surprised if it was still the same, just so as not to break people's code.)
well, it was a well-known library about 20 years ago, but i think the original btrieve data engine has the worst api ever written. almost everything goes through a single call, with each of its many parameters containing a different value depending on which call you're really doing (one parameter was a flag telling the system if you wanted to open a file, close a file, search, insert, etc). i liked btrieve way back then, but i spent a long time making a good abstraction layer.
it could have been easily improved by not forcing everything into one call. not only was the one call hideous, but the programmer was responsible for allocating, passing in, and freeing the position block ... some memory used by btrieve to track the open file handle, position, etc. another improvement would be to allow ascii text to be used when defining the indexing. indices had to be specified by a convoluted binary representation.
best regards,
don
A lot of the CRT library functions are poorly or vaguely named possibly due to legacy coding restrictions back in the day and thus require frequent use of the F1 key for people to find the right function and supply the right arguments.
I've been using CRT functions for a while and I still find myself hitting F1 a fair amount.

Readability of heavy function call nesting?

I've often seen it argued that heavily nested function calls should not be used because they are unreadable. However, using temporary variables instead creates a lot of unnecessary verbosity and forces the reader to mentally link each temporary variable to what it represents. When looking at the way Lisp code is typically formatted, it occurred to me that nested function calls can actually be made quite readable if you format them to reflect the nesting. For example:
// Totally unreadable:
auto linesIter = filter!"a.length > 0"(map!strip(File(filename).byLine())))
// Perfectly readable. The only difference is formatting.
auto linesIter = filter!"a.length > 0"(
map!strip(
File(filename).byLine()
)
);
// Readable, but unnecessarily verbose:
auto rawLines = File(filename).byLine();
auto stripped = map!strip(rawLines);
auto filtered = filter!"a.length > 0"(stripped);
Writing something like the first example in nested function form is, IMHO, equivalent to doing the following in more procedural-style code:
for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++) { if(x < 2) { z++; } else { y++; }}}
In both cases the real problem is poor formatting, not excessive nesting. How would you rate the readability/comprehensibility of the well-formatted nested function version vs. the temp variable version? Do you think heavy function call nesting is bad style even if it's formatted for maximum readability? If so, why?
I see nothing wrong with breaking large nested function calls in the way you have using formatting. It's readable, which was the intention.
With temporary variables, I try to avoid them. And the only reason for this is quite simply, I am utterly incapable of giving them good names. I try when they are absolutely necessary, and end up wasting 5 - 10 minutes thinking 'what would be the good name for blah blah that does cor blimey'? And almost always end up giving up and using buffer if it's an array, or temp if it's a scalar, etc.
That said, with your nested structure, the functions represent verbs, and not the products of the verb's action, which is what you'd get with temporary variables. With temporary variables, you do get a chance to give that product a name. But if it's a thing that is better described by the verb and direct object themselves (verb(directObject)) then that's the route you should take.
You say "using temporary variables instead creates a lot of unnecessary verbosity and forces the reader to mentally link each temporary variable to what it represents" -- but IMO that's just another way of saying that you've broken up the thing into steps that the reader can understand one at a time -- in other words, you've made it more readable.
I'm quite happy to add an extra variable to break a long line up into seperate steps (your example 3), but the key thing for me is whether you can break the thing up cleanly into genuine steps. One good indicator is whether you can find a good variable name; if you can't, maybe it's not a genuine seperate step that needs splitting out.
There's nothing much wrong with your example 2, but much longer than that and I would certainly break it up. You'll thank yourself when it comes to debugging...
IMHO, objects and names should be carefully chosen so that things are readable when you do the function-style coding of slamming everything onto one line like in your first example. If it is totally unreadable, somebody(s) chose bad names. Your goal is that if something looks off, often times it means there is a bug.
In the real world when you have to deal with those badly-chosen names, there isn't anything wrong with creating temporary constants (or even routines) with proper names to clean things up a bit. It beats a comment, because it compiles and is easier to modify.
I personally think that if there is no performance penalties readability is more important. Although i do not know anything about the Lisp syntax, looks like your examples makes the same number of calls? If thats the case, do it readable way. But if you are calling a heavy function (like opening a file and reading again and again) more times in a loop, you should avoid it. I hope this answer is useful.
I prefer not to use too many variables b/c they are often the source of bugs. If I can express something as a single expression I prefer it that way. I would probably go with your second example.

Resources