ID:152945
 
(I posted this in Design Philosophy because I feel it is a main discussion on different codeing styles of various programmers.)

A while ago when I received the publication e'mail for my search demo, it said that:
"Mobius Evalon's space2plus() proc is terrible, since it really should be done
with either findText() or text2ascii()"

My question is why?

proc
space2plus(string as text)
for(var/i=1;i<=length(string);i++)
if(copytext(string,i,i+1) == " ") string = copytext(string,1,i) + "+" + copytext(string,i+1)
return string


This proc does exactly as it's designed to do. text2ascii() isn't necessary at all. Unless someone’s planning on sitting there and typing "something[alt 0160]to[alt 0160]search[alt 0160]for" (0160 is the ascii code for space.)
Otherwise it works fine.

What’s the perperse of nitpicking the way something is done if it uses good programming principles and does as it's ment to do?
text2ascii() is a lot faster than copytext(). Therefore, if you're trying to get a single character out of a string, you should use text2ascii().

findText() would be good here because using findText(), you could change all of the spaces in a string into addition signs without having to loop through each and every character in the string.

If you're trying to teach somebody to do something, you should teach them to do it as well as possible!
In response to Wizkidd0123
I don't know how much better text2ascii() would be, but the findtext method is lot more bloated than his current setup:

proc
space2plus(string as text)
var/strlen = length(string)
if(strlen>1)
var/space = findtext(string, " ")
while(space)
var/part1 = copytext(string, 1, space)
var/part2 = copytext(string, min(space+1, strlen))
if(space==strlen)
string = "[part1]+"
else
string = "[part1]+[part2]"
space = findtext(string, " ")
else if(string == " ") string = "+"
return string


~X
In response to Xooxer
I should have thought more before posting -- thanks for correcting me, Xooxer!

I'm really sorry about giving you bad advice, Tiberath. The advice about text2ascii(), however, was correct:

I put three versions of the proc up for comparison: One was an optimized version of your findtext()-using space2plus(), another was Mobius's (uses copytext()), and another used text2ascii(). The text2ascii() model was the fastest; findtext() the slowest.
In response to Wizkidd0123
Yeah, a test I ran clocked the text2ascii() version I made to be about 61.927% faster than the copytext() version. This was after running each one 1 million times and calculating the Real Time difference. The copytext() version had a Real Time of 335.967, while the text2ascii() version rang in at only 207.480.

proc
space2plus(string)
for(var/i=length(string); i>0; i--)
if(text2ascii(string,i) == 32)
string = copytext(string,1,i) + "+" + copytext(string,i+1)
return string


I reversed the for() loop to decrement through the characters rather than increment, as either Tom or Dan said this was the fastest type of for() loop, besides using the "in" operator. I think they said while() loops are slightly faster than that. That probably makes this the fastest possible version of the proc.

[Edit] Oh, and I reversed the for() loops on both procs before running the tests, so that increase in speed is not shown here. I could run a test between his old proc and the new reversed copytext() version to get a speed increase rating for that.

~X
In response to Xooxer
Xooxer wrote:
[Edit] Oh, and I reversed the for() loops on both procs before running the tests, so that increase in speed is not shown here. I could run a test between his old proc and the new reversed copytext() version to get a speed increase rating for that.

And test I did! It looks like the decremental version of the for() loop is about 9.248% faster than the incremental version. This was after 1 million calls each, and calculating the Real Time taken by each proc. I wonder if it could get any faster....

~X
In response to Xooxer
Xooxer wrote:
I wonder if it could get any faster....

Surprise surprise, it can! Using a while() loop method, rather than the for() loop previously incorporated, I was able to increase the fastest version by another 6.521%, making this the current champion of the bunch:

proc
space2plus(string)
var/i=length(string)+1
while(--i)
if(text2ascii(string,i) == 32)
string = copytext(string,1,i) + "+" + copytext(string,i+1)
return string


Ok, that's probably about as fast as it will get.

~X
In response to Xooxer
Xooxer wrote:
I reversed the for() loop to decrement through the characters rather than increment, as either Tom or Dan said this was the fastest type of for() loop

Interesting. Why is a decrementing for() loop faster than an incrementing for() loop? Did Dan (or Tom) tell you?
In response to Wizkidd0123
I'm sure they did, but I can't seem to find the post now. I do recall (I believe it was Dan, seems like the sort of thing he would clue in on) them saying that a decremental for() loop was slightly quicker. Perhaps it has something to do with the operations required to accomplish incrementing verses decrementing. :\

~X
In response to Xooxer
Possibly it's because when incrementing you have to test against length(string) every loop, so length() has to be evaluated every time; and function calls are slow, especially in a virtual machine language like DM. When decrementing, you just test against 0, which is faster to evaluate.
In response to Xooxer
It doesn't have to be bloated, and it evens goes faster than your current champion unless the string is all spaces (it which case it's the same). =)

proc
spacetoplus(string)
var/space=findtext(string," ")
while(space)
string=copytext(string,1,space) + "+" + copytext(string,space+1)
space=findtext(string," ",space+1)
return string


I can't shake the feeling that I might be missing something, so please double-check my results.
In response to Crispy
That makes sense -- thanks, Crispy! =)
In response to Crispy
Crispy wrote:
Possibly it's because when incrementing you have to test against length(string) every loop, so length() has to be evaluated every time; and function calls are slow, especially in a virtual machine language like DM. When decrementing, you just test against 0, which is faster to evaluate.

Indeed this is the case. I learned this some time back either in a book on optimization or in an online tutorial for a language. (I believe it was a site on optimizing Java performance.) This principle in general holds true: When comparing to a non-constant value, especially to something that calls a function, it takes longer.

One notable exception is Visual Basic. In a FOR loop there, the end value is computed in advance and never updated. This seems illogical to me, but then I suppose it's not too much unlike BYOND's habit of copying a list before using for(item in list). When this is the case, the operation is much faster because the function is only called the first time. Similarly, in BYOND for(thing in view()) is somewhat speedy because it only calls view() once.

Lummox JR
In response to Lummox JR
(This topic took off better then i thought it would)

You all hold good arguments and I can see upsides and downsides. But none the less, the current space2plus() proc works as intended, so calling it terrible was a bit uncalled for.

But, now I wonder, why would the speed really matter for such a thing?
The time it takes for the computer to pull either proc off is unnoticeable to the human eye, also, wouldn't it also matter on the speed of the computer itself?
And also, wouldn't you need to know ASCII script to be able to use text2ascii() properly?
If this is the case many people aren’t going to go out of their way to learn them, especially if they are in a rush to get things done by a set release date.

In response to Tiberath
Tiberath wrote:
the current space2plus() proc works as intended, so calling it terrible was a bit uncalled for.

Perhaps "terrible" was a bit much, but really, it's one of the worst ways to be pulling a single character out of a string.

But, now I wonder, why would the speed really matter for such a thing?

More important than space2plus() is the method that space2plus() uses.

Remember, the user of a demo will be learning from that demo. If you use a certain method to do something in your demo, potentially, the user could learn to do the same thing. Therefore, in demos, it's very, very important that the absolute best method be used every time.

Although the speed probably won't be much of an issue in your situation, if the user were to get single characters out of a string hundreds and hundreds of times, the speed difference between the different methods available could really become an issue. If my DM Syntax Highlighter library used the copytext() method of pulling single characters out of strings, it would definitely be a lot slower!

also, wouldn't it also matter on the speed of the computer itself?

The speed difference between procs run on different computers is proportional. If proc x() is faster than proc y() on my computer, proc x() will be faster than proc y() on your computer too.

And also, wouldn't you need to know ASCII script to be able to use text2ascii() properly?

ASCII is basically a collection of numbers that each represent a character. ASCII isn't really something that needs to be learned -- its definition (see previous sentence) is really all you need to know.


Look how easy it is to use: for example, if you want to see if a string starts with say, a space, the following would be fine:

proc/starts_with_space(string)
//if the first char in string is a space
if(text2ascii(string,1) == text2ascii(" ")) return 1
return 0


Since text2ascii(" ") returns the number, 32, the following proc would be the exact same thing:


proc/starts_with_space(string)
//if the first char in string is a space
if(text2ascii(string,1) == 32) return 1
return 0
In response to Wizkidd0123
also, wouldn't it also matter on the speed of the computer itself?

The speed difference between procs run on different computers is proportional. If proc x() is faster than proc y() on my computer, proc x() will be faster than proc y() on your computer too.

That wasn't what I was getting at. Above they were discussing the different speeds of executing a proc.
I imagine the speed would be different form an 800 MHz compared to a 3 GHz.
In response to Tiberath
Tiberath wrote:
That wasn't what I was getting at. Above they were discussing the different speeds of executing a proc.
I imagine the speed would be different form an 800 MHz compared to a 3 GHz.

Oh -- you mean between YMIHere and Xooxer's computer. That's a good point. =P

Either way though, both the findtext() and text2ascii() methods are definitely faster than the copytext() method.
In response to Tiberath
We've got other procs to test them against. I just grabbed his off of the forum to test against mine. =)
In response to Tiberath
Tiberath wrote:
(This topic took off better then i thought it would)

You all hold good arguments and I can see upsides and downsides. But none the less, the current space2plus() proc works as intended, so calling it terrible was a bit uncalled for.

The old method was wasteful of both memory and speed for no reason.

But, now I wonder, why would the speed really matter for such a thing?

Because speed almost always matters.

The time it takes for the computer to pull either proc off is unnoticeable to the human eye, also, wouldn't it also matter on the speed of the computer itself?

Indeed, since you can't control the speed of the computer it'll be used on, you should take care to keep the code fast and simple. You never know if space2plus() is gonna end up in a tight loop or something and that speed could make a big difference. Even if that's not likely, you should strive to make it good, not just adequate.

And also, wouldn't you need to know ASCII script to be able to use text2ascii() properly?

Aye. So learn it.

If this is the case many people aren’t going to go out of their way to learn them, especially if they are in a rush to get things done by a set release date.

Considering this is for a demo, the only one who needs to know the ASCII value for a space here is you. This doesn't really impact anyone's release date.

Lummox JR