I have relational predicates with the first and last argument an assoc, and in the middle one or two additional arguments. I want to exchange one of the “middle” arguments from a single variable to a pair – to pass additional information.
I am wondering what the overhead might be to have pairs as arguments in the middle?
Dan,
As a general software practice it is not a good idea to “optimize early” without doing any measurements. It is better to solve your problem in the most elegant way, and then measure to see where you need to optimize.
“early optimization” is productive mostly when you are chosing the algorithm and not for single lines of code.
I have made a “strategic” decision about a year ago to write the system I am envisioning in Prolog, rather than, say, C/C++.
I knew at the time that I am sacrificing performance but it was, in my mind, the right choice, since there were significant outstanding problem domain issues to be solved.
I have now obtained some good results, and I want to see how far i can optimize, while staying within swi-prolog.
In particular, I want my program to also run well on a low resource environment such as
for example, mobile devices (while trying out things in Termux).
I am now reexamining choices i have made in critical program areas to see if better choices can be made – that optimize within the prologs programming model (e.g. better approaches to argument passing), while also looking out for ideas that are closer in spirit to C / C++, eg. binary manipulations, pointers and linked-lists, pre-allocations (to reduce GC), perhaps even memory access locality, but nevertheless enable me take most full advantage of Prolog’s capabilities
Flat argument lists in principle faster. The total impact depends a bit what happens afterwards though. If the one/two argument(s) are passed along a couple of times to called predicates, using a compound may win.
In practice I don’t think the result will be significant. Only when dealing with tabular data it is wise to avoid nesting. Well, unless the data is not uniform and making everything flat would imply many NULL/meaningless entries.
What about wrapping a flat argument list into a dict.
Also, what about a pair instead of two arguments.
In cases, indexing does not play a role, just the overhead of passing the args across a possibly deep recursive calls, across several goal predicates various calls.
I prefer the “pair” form because it makes my code easier to read and reduces my chances of making a mistake. I also use DCGs or EDCGs where possible to reduce the number of arguments (many of my predicates would have 8-12 arguments if I didn’t used EDCGs, and that’s too many).
Most will probably in the category “barely measurable”. In tight loops it may make a significant difference, but it all depends on the details and there is no guarantee that the differences are still there the next version. First step is to use the profiler to see whether there is anything worthwhile to gain anyway. Then run some experiments.
The program area where these parameters are passed are highly critical for performance, since these are performed very significantly more times, than other areas of the program, so i believe things will add up.
Also, from profiling i noticed that there are some peeks I will address and then some distribution of processing that, I think, needs to be reduced as well by creating uniformely a better performance characteristics.
But, indeed, i will need to do more experimenting to pick things up.