Optimization

BlitzMax Forums/BlitzMax Programming/Optimization

TwoCorin517(Posted 2008) [#1]
I'm curious as to see which is more optimized. An Array of Chars or a String.

would:
type TString
Field Chars[]:Char
field NumChars:int
method Print()
local LoopVar:int
for LoopVar = 0 to NumChars
print Chars[LoopVar]
next
end type

And using it like:
Hello:TString = new TString
Hello.NumChars = 4
Hello.Chars:Char = new Char[Hello.NumChars]
Hello.Print()

Would that be more Optimized than:
Hello:String = "Hello"



grable(Posted 2008) [#2]
No.

If its speed your after, your looking in the wrong place for optimizations ;)

Alternativly you could use 0 terminated strings, with all the problems that come with them. But i dont reccomend it.


ImaginaryHuman(Posted 2008) [#3]
The print statement is very slow especially if you're calling it for every character. It's faster to print a whole line at a time.

But manipulating characters as an array is probably as fast as using strings.

Also my take is that almost everything can be optimized and just because there are areas of an application which might show more of a speedup from optimizing them, it doesn't mean you shouldn't optimize also small parts. For me it's a part of the art of programming.


grable(Posted 2008) [#4]
Also my take is that almost everything can be optimized and just because there are areas of an application which might show more of a speedup from optimizing them, it doesn't mean you shouldn't optimize also small parts. For me it's a part of the art of programming.

Sure, i agree. But you dont start with optimizing for those 0.1% speed increases when there are better places to start do you?


N(Posted 2008) [#5]
The most optimized form is currently the default BMax string. Using anything else, you would more likely be increasing the memory requirements per string, not to mention decreasing the speed at which you are able to manipulate them.

If you really want to use C strings and optimize to your heart's content, you're better off just using C.


ImaginaryHuman(Posted 2008) [#6]
Why not ;-D If you intend to do them all you might as well start anywhere. Optimization after the fact is often a result of poor design and wrong choice of algorithm implementation. If you get it right the first time you don't need to go back. I like to be sure that I am totally satisfied with how something works before moving on.


FlameDuck(Posted 2008) [#7]
What Noel said. Also, preemptive optimization is pointless.


Arowx(Posted 2008) [#8]
Got to agree with flameduck, on that one, the old 80/20 rule usually applies 80% of your code won't be used often enough to need any optimisation and the 20% that does you will only find when you analyse the performance of your code.

9 times out of ten your code wastes most of it's time where you least expect it to!

However I would say that the key to good 'pre-emptive optimization' is picking the right data structure for the job!

It could help this discussion if you would indicate what you are trying to do?


big10p(Posted 2008) [#9]
'Strings' are just arrays of chars - in C, at least.

Again, I doubt this should be your primary target for optimization.


ImaginaryHuman(Posted 2008) [#10]
I disagree and it's not just about whether it is `useful` or not to optimize. I also don't see why it's pointless to optimize up-front unless you're thinking that you will only optimize parts which are the most troublesome, which is not my thinking. I do agree there may be insights to have afterwards as to which areas can be better optimized but there is also something to be said for starting out with a solid foundation.


ziggy(Posted 2008) [#11]
@bg10p: You will agree, at last partially, that there no data type char on BlitzMax, so in this particular case we're comparing Strings with arrays of Strings.

I also agree with Noel and Flameduck


N(Posted 2008) [#12]
I disagree and it's not just about whether it is `useful` or not to optimize. I also don't see why it's pointless to optimize up-front unless you're thinking that you will only optimize parts which are the most troublesome, which is not my thinking. I do agree there may be insights to have afterwards as to which areas can be better optimized but there is also something to be said for starting out with a solid foundation.
If the optimization decreases how well understood the code is, requires documentation, and does not impact anything, it's a pointless optimization. When you optimize code, you target the parts of your code that take a large amount of time to execute, especially when it's executed repeatedly and will drag overall performance down. You do not, however, optimize a string, when it is fine as-is and does not impact your program's speed at all.

Starting out trying to write the most optimized code will just result in your working on a single function that does close to nothing, until finally you've either written it in C, ASM, or given up. The point is to make progress, not to write the absolute most efficient code right away. If you try to do that, you're just being stupid and ignoring the fact that you need to get everything working before you can really know what needs to be optimized.


ImaginaryHuman(Posted 2008) [#13]
Well, you're all allowed your different opinions and just because you are really sure that your approach is correct does not mean that I need comply or agree, or that I am what you think of me if I don't.

Also stating what you believe to be the right way to go about something, as if it is THE way, does not make it so, and I will still continue as I have been and making plenty of progress at the same time, thank you very much. Feel free to do the same.


Michael Reitzenstein(Posted 2008) [#14]
That's the thing though, it IS 'the' way. Premature optimization is a very bad thing to do. It is a counterproductive way of spending precious developer cycles. It often makes code slower, and always makes code harder to read.

Profiling is cheap, quick and revealing. No experienced developer believes that they'll know in advance what the bottleneck of their application will be, because computers, programming languages and applications are FAR too complex to reason about with respect to performance.

Two famous and relevent quotes:

"Premature optimization is the root of all evil." (Knuth, paraphrashing Hoare)

"Programs must be written for people to read, and only incidentally for machines to execute." (Albert & Sussman in SICP)


remz(Posted 2008) [#15]
This discussion is interesting, although we are steering a bit off the initial question.
2Corin517, could you post a bit about what you intend to do with those famous optimized strings, maybe the community would then be able to suggest solution.

Michael, I agree with you that early optimization are generally bad, that goes with the 3 steps of coding:
1) Make it WORK
2) Make it PRETTY
3) Make it FAST
Since most project don't reach the 'work' stage.. And pretty is often 'fast' by itself because a good and clean design with small functions and adequate data structure is most of the time fast enough.

However, there are cases where speed is important: I am trying to do a pseudo-3D game that would run on a cellphone, and since CPU ressource is very limited, making the game 'work' also means making it 'fast' because unless its running fast enough, it's NOT working.

So that's why I think the most important thing is knowing what's the problem, before we start suggesting solutions ;)


ImaginaryHuman(Posted 2008) [#16]
I'm glad these approaches work for you. They don't work for me.

Developer cycles are not precious. If your code is placed under a compression of time, based on trying to meet a deadline, then your application starts to experience compression - usually a loss of quality. I tend to prefer quality over quantity and that means the time is not important.

As to making code slower, obviously that would only be the case when you have not finished optimizing properly. As to making it harder to read, that part is probably true but if you're the only one reading it who cares.

Also those famous quotes are meaningless, anyone in any specialty to twist words to make it sound like you should or shouldn't do something. It's cute but not meaningful.

Also there is no `the` way to do anything, ever. Behavior does not matter. It is where you are coming from that is important, not the form it takes.

It probably just comes down to personality. I like to make sure that I am doing the best I can and that the solutions I'm choosing along the way are the most appropriate for the task in terms of both efficiency and freedom. Usually efficiency and freedom should go hand in hand. I like knowing that I've chosen the best possible option/algorithm/approach and that I've implemented it to the best state that it can be in before I move on. That way I know I have a solid foundation to build upon and when I come back to it I am always pleased with how it turned out. That's just the way I work. I don't think there's anything wrong with that. I am not bothered by it so you don't need to be bothered by it for me.


Czar Flavius(Posted 2008) [#17]
Do you know what would be fun? Trying to make programs as bad as possible.


big10p(Posted 2008) [#18]
@bg10p: You will agree, at last partially, that there no data type char on BlitzMax, so in this particular case we're comparing Strings with arrays of Strings.
Fair enough. TBH, I don't actually own bmax so am not quite sure why I'm posting here, anyway. :)


Gabriel(Posted 2008) [#19]
I love people who optimize without profiling, and I actively encourage them, providing they're already minded to. I gave up trying to convince people they were making their life difficult and came to the (somewhat selfish) realization that they were simultaneously making my life easier, so good luck to them.


big10p(Posted 2008) [#20]
I think this kinda thing just comes with experience - you just learn what the best way to do things is. As others have said: finish the damn thing then do your optimizations. :)


FlameDuck(Posted 2008) [#21]
Developer cycles are not precious.
Maybe "expensive" is a better word.

I tend to prefer quality over quantity and that means the time is not important.
I tend to prefer "food on the table". So time is very important. If it meets the customers performance requirements (they don't usually have any explicit performance requirements, most are of the functional variety) it's fast enough.

As to making it harder to read, that part is probably true but if you're the only one reading it who cares.
You should. Besides, the probability of only one person working on a sufficiently large and/or complex piece of software (one likely to require optimization) over the 20 something years of its life cycle is so small it's not statistically significant.

Also there is no `the` way to do anything, ever.
Sure there is. It's called the "SPOT" or "Single Point Of Truth" rule.

I like knowing that I've chosen the best possible option/algorithm/approach and that I've implemented it to the best state that it can be in before I move on.
But that's just the point. There is no way you could POSSIBLY know up-front what the best or most effective solution to any given problem is. Even if you use Design Patterns religiously there will be occasions were the method you've chosen might work well in theory, problems never manifest themselves until the software has been deployed.

Do you know what would be fun? Trying to make programs as bad as possible.
Get a job at Microsoft.


ImaginaryHuman(Posted 2008) [#22]
I disagree. Waiting for the problem to happen and then addressing it means that you did not understand the full ramifications of the concept you tried to implement beforehand and are only now finding out side-effects to it that you didn't understand. If you fully understand what you're doing at the beginning there are no nasty surprises later.

Also there is no truth in the world, truth is beyond the world.


Gabriel(Posted 2008) [#23]
If you fully understand what you're doing at the beginning there are no nasty surprises later.

To borrow a line from Donald Rumsfeld, you never know that you fully understand. Sometimes you think that you fully understand, and many times you may be right, but at some point you will always fail to fully understand. The only remaining question is whether, when that happens, you know that you don't know or you don't know that you don't know. I like to know when I don't know.


big10p(Posted 2008) [#24]
I disagree. Waiting for the problem to happen and then addressing it means that you did not understand the full ramifications of the concept you tried to implement beforehand and are only now finding out side-effects to it that you didn't understand. If you fully understand what you're doing at the beginning there are no nasty surprises later.
It's not a case of 'waiting for a problem to happen' - problems will arise, whether you like it, or not. No matter how experienced you are, and no matter how much you plan beforehand, you'll (almost) always be able to find optimizations when the app is 'finished'. Especially where big apps are concerned. Therefore you should simply develop with the knowledge and experience you have, then optimize later on. You can't possibly envisage the entire app and optimize beforehand.


FlameDuck(Posted 2008) [#25]
If you fully understand what you're doing at the beginning there are no nasty surprises later.
Yes there are. Besides the unknown unknowns Gabe and big10p refer to, it is improbable that, for any sufficiently advanced system:
a) You will fully understand the system in the first try.
b) The purpose and scope of the system (and thus its requirements) never change over the course of the product development cycle (never mind its entire lifespan).
c) A single person, capable of memorizing only 7 things (+/- 2) in their short term memory, without basic guidelines like SPOT, DRY and YAGNI will not be able to fathom at once, a program with more than 7 (+/- 2) states.

"Always implement things when you actually need them, never when you just foresee that you need them" - Kent Beck.

Also there is no truth in the world, truth is beyond the world.
Except if there is no truth in the world, that statement is false, and thus there must be at least ONE truth in the world.


ImaginaryHuman(Posted 2008) [#26]
You guys are such disbelievers in anything outside of your mindset. You've obviously learned a lot of stuff from a number of sources that all seem to be justified and reliable, but they're all nonsense. The only rule is that rules mean nothing. Reinvention of the wheel is necessary for revolution, and having a vision is necessary for success. I think your approaches are backwards and archaic. But we're going to disagree until the cows come home so this is where I exit the thread.


Michael Reitzenstein(Posted 2008) [#27]
No, it's because letting go of minor performance tweaks and focusing on the quality of the code is something we've all learned the hard way.

I'm not saying you aren't an effective developer, I'm saying you'd be a more effective developer if you focused on the quality of your code.

The quotes weren't twisted or misinterpreted. Knuth, Hoare, Albert and Sussman all strongly discouraged premature optimization. If someone who coauthored SICP told me that my technique was wrong, I know I'd pay attention and consider the possibility (reading SICP was like that).


grable(Posted 2008) [#28]
ou guys are such disbelievers in anything outside of your mindset. You've obviously learned a lot of stuff from a number of sources that all seem to be justified and reliable, but they're all nonsense. The only rule is that rules mean nothing. Reinvention of the wheel is necessary for revolution, and having a vision is necessary for success.

Welcome to the internet! ;)

The quotes are good advice, but should not be taken as gospel. Like with anything people find what works for them and stick with it.
There is no absolute right way to do anything IMHO.


N(Posted 2008) [#29]
There is no absolute right way to do anything IMHO.
You say that now, but what happens when you have to make a right turn?


Sledge(Posted 2008) [#30]
He goes left and left and left until he's pointing right, like a proper modernist, you outmoded decadent oafs.


grable(Posted 2008) [#31]
You say that now, but what happens when you have to make a right turn?

Id say when a discussion comes down to semantics theres really no point in continuing.
But since this is probably a joke, "haha" :)


FlameDuck(Posted 2008) [#32]
You guys are such disbelievers in anything outside of your mindset.
As it turns out, software development is not a religion. It's not a matter of what you believe, it's a matter of what the evidence shows is likely.

The only rule is that rules mean nothing.
Prove it.

Reinvention of the wheel is necessary for revolution
Actually, revolution by definition, is not a reinvention of the wheel. It's completely circumventing the wheel all together. Like say with the evolutionary software paradigm (See: Computers in Context: The Philosophy and Practice of Systems Design) or with lean/agile development processes.

and having a vision is necessary for success.
Explain Microsoft.

I think your approaches are backwards and archaic.
Fair enough. However keep in mind that your approach is even older. Early optimization was a good thing 30 odd years ago when developers had to compete for time on the only computer in their state and/or country. Back when CPU time was scarce and developer time was in abundance - sure, optimize away to your hearts content. Today however the situation is reversed. Not only can you buy more computer power for a trivial amount of money than the entire world had back then, but getting someone to competently program it is a real challenge.

There is no absolute right way to do anything IMHO.
Then why optimize? If all possible solutions are equally correct, optimization is no longer just pointless, it's now futile as well.

No, it's because letting go of minor performance tweaks and focusing on the quality of the code is something we've all learned the hard way.
Exactly.


jhocking(Posted 2008) [#33]
Getting beyond these computer science-y debates about premature optimization, I rarely think much about optimizing code for the simple reason that the code is rarely the bottleneck in any of the things I program. By that I mean, in the games I develop, the polygon counts and texture sizes and what not have a much greater effect on the framerate of the game than anything in the code itself. With the code I'm just concerned about getting the program to do what I want to have happen; when I'm concerned about speed I'm always looking at the art assets.


grable(Posted 2008) [#34]
Then why optimize? If all possible solutions are equally correct, optimization is no longer just pointless, it's now futile as well.

If correctness is your only goal, sure.


FlameDuck(Posted 2008) [#35]
If correctness is your only goal, sure.
So what you're saying is that if you have some other goal than "correctness" (however you define that), then there IS an absolute right way to do something?


jhocking(Posted 2008) [#36]
I like to be sure that I am totally satisfied with how something works before moving on.

Oh yeah and I forgot to bring this up before, but nobody is saying that speed isn't any concern or that you shouldn't be trying to write efficient code from the start. However, realistically there is always some point where you decide "okay this is fast enough, now to move on to the next task" (otherwise you would literally spend forever just trying to get "Hello World" to run faster.) That point is precisely what you described, when you are satisfied with how it works, and should probably be sometime well before you start optimizing strings.

As an even clearer example of silly optimizing, think about floating point math. Sure it would run fractionally faster if you always replaced all of your floating point math with integers, but do you optimize the routine every time you multiply a couple of numbers together? (If you do then I suppose this really is just a difference of opinion and it's not like anyone is going to convince you.)

That all said, I think everyone has something where they know in their head it doesn't really matter but they obsess about it anyway. In my case, I'm constantly fretting about if there's a more efficient way to setup my if/else statements. I know this makes essentially no difference, but I'm constantly fiddling in order to minimize the number of condition checks the computer needs to make. Silly but that's just a nervous habit of mine.


ImaginaryHuman(Posted 2008) [#37]
Yah, it goes back to the assembly language days with relatively slow processors trying to squeeze every CPU cycle out of it, and especially like in demo coding where you're trying to be as utterly efficient as possible in order to make the hardware appear to do things that other people thought was beyond its limits.

Of course there is a place where you stop optimizing and move on, but for me where I draw the line as to when I need to optimize just happens to be a little sooner than most.

I appreciate your comments also Flameduck, and you are a well-read and technologically accomplished chap, but I will just have to disagree with what you believe to be the way to do things. Nothing personal.

Okay, back to trying to run a 3D engine in 2 lines of code..


Arowx(Posted 2008) [#38]
Wow this topic has really taken off on the academic/belief side of things so lets get back to basics...

Type TString
	Field Chars:Byte[]
	Field NumChars:Int
	Method Write()
		Local LoopVar:Int
		For LoopVar = 0 To NumChars
			Print Chr(Chars[LoopVar])
		Next
	End Method
End Type

testLoopMax = 999999

start = MilliSecs()

For loopy = 0 To testLoopMax
	Hello:TString = New TString
	Hello.NumChars = 4
	Hello.Chars = [Byte(Asc("H")),Byte(Asc("e")),Byte(Asc("l")),Byte(Asc("l")),Byte(Asc("o"))]
	'Hello.Write()
Next

time1 = MilliSecs()-start

start = MilliSecs()

For loopy2 = 0 To testLoopMax
	Hello2:String = "Hello"
	'Print Hello2
Next

time2 = MilliSecs()-start

Print "TString Hello x "+(testLoopMax+1)+" = "+time1+"ms"
Print "String  Hello x "+(testLoopMax+1)+" = "+time2+"ms"



Gives the following results on a 800 Mhz Athlon ;o)

TString Hello x 1000000 = 1243ms
String  Hello x 1000000 = 2ms


Does this answer the original question, or should we be storing our Bytes in a linked list?


TwoCorin517(Posted 2008) [#39]
Merx: That answers it pretty clearly.
Imaginary Human: I've solved how to write a 3d engine in 2 lines of code:

:D

I've not done much optimization at all, (obviously) where is the place to start?


plash(Posted 2008) [#40]
TString Hello x 1000000 = 521ms
String Hello x 1000000 = 1ms


ImaginaryHuman(Posted 2008) [#41]
You could try the old fashioned way - write it, make it run, see how fast it was, try writing it another way, test it again etc.


Retimer(Posted 2008) [#42]
If you are truly looking for optimizing, can I suggest creating a large (few hundred line) template, and time as many different popular functions that you'll need & use in it, including drawing functions if your application is not server-based.
Download several other language compilers (Blitz, erlang, python, java, c++ (dev-cpp/visual c++), .net langs, web-based [php,cgi] if server-based, etc).

Convert that template to work with these languages, and compare all the results. Not only will you save time in not having to switch languages several times just to 'improve' your application, but you'll smash yourself into your ultimatum in coding languages. It's a great learning experience as well. Optimizing your code in a language that does things at an average rate of 50% slower than another can be pointless (Although you need to take into consideration the speed at which you can cough applications out in that language).

It would be the same as testing different databases. In the end it only does you a favour of saving time, and in some cases...money.
"You can spend a year making a pong game if you don't plan it before the start."