Raised This Month: $32 Target: $400
 8% 

String Slicing


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Twilight Suzuka
bad
Join Date: Jul 2004
Location: CS lab
Old 09-28-2007 , 08:14   String Slicing
Reply With Quote #1

An important optimization that is a little counter intuitive is PAWN string slicing, best shown in the following example:

SUMMARY: By passing an indexed array (my_array[5] instead of my_array) into a function or native which accepts an array, the index you pass in becomes the base of the array the function you called accepts.

So, if you pass in my_array[5] to my_func, then when my_func does your_array[0], it is the value of my_array[5].

LONGER EXPLANATION:
Code:
public test()
{
	new str2[100] = "y halo thar"
	test2(str2[2]);
}

// This shows that its not a fluke or a compiler optimization
public test2(str[])
{
	test3(str)
}

public test3(str[])
{
        // Writes "halo thar" to file
	write_file("addons/amxmodx/test.ini",str);
}
To most, this would be assumed to be a compiler error. After all, it looks as if you are simply handing test2 a cell indexed FROM the string, not a string itself!

This is a primitive form of "array slicing", which can be done with any kind of array. It lets you cut out a subset of the array by telling where you want the array to start at when you pass it. True array slicing can do a lot more, but this is the same amount that C affords us natively using pointers, so we can't be picky.

USES:

Why is this useful? Well, for one thing, it can allow us to do a lot of operations without calls to natives. For example, usually when you want a subset of the string, you have to use copyc or format to get it out, therefore using a native call AND allocating a buffer onto the stack (costly due to zeroing).

However, what if you don't REALLY want a new copy; it'd be perfectly fine if the old copy was messed with and mangled, you just don't want the front part? Or, what if you aren't even going to edit the string; you just need to cut a part out? In that case, string slicing is the only real way to do it, unless you want to go to costly natives like format. Here is a peice of code which makes this easy to understand:

Code:
new str_to_cut[] = "Cut us here| Woah important info"

stock testfunc(str[])
{
	new i = containi(str,"|")
	parse_me(str[i])
}

stock parse_me(str[])
{
	// Do stuff on string AFTER pipe
}
We still use a str function: containi. However, to do stuff in "parse" normally, we'd have to pass in i, and do all offsets based on i. This is extremely cost ineffecient, ugly to look at, and hard to understand (and thus error prone). The string slicing method is a lot cleaner.

Obviously, there are better examples; for instance, the one I am quite fond of is for using in set_task. Instead of using explode (costly) or strtok (costly), if we assume we don't really need nor care about keeping the integrity of the string (which is almost always the case; you use parts of the string, then you don't use them again, therefore you can ruinate them all you want) then the string slicing alternative becomes a lot more cost efficient.

Another example is when you wish to stuff non-string data at the beginning of a string, for space or efficiency reasons. In some of my newer code, it is often the case that stuffing a few integer values at the beginning of a string is more portable than enum based structs, and a lot simpler to understand in code; what was perhaps 4 integers and a string being passed into another plugin, saved somewhere, only to be passed back without ever being parsed, is now one array. Quite a lot easier on the eyes.

A full explanation of how string slicing works is attached to this post, if you care to read it; I do not guarantee its validity, as it is quite early in the morning.


Good night.
Attached Files
File Type: txt string slicing.txt (2.3 KB, 468 views)
__________________

Last edited by Twilight Suzuka; 09-28-2007 at 08:16.
Twilight Suzuka is offline
Send a message via AIM to Twilight Suzuka Send a message via MSN to Twilight Suzuka
purple_pixie
Veteran Member
Join Date: Jun 2007
Location: Winchester, England
Old 09-28-2007 , 08:48   Re: String Slicing
Reply With Quote #2

Well if that didn't just make my life a little easier ...

You, my friend, are a legend.

String manipulation ftw.

EDIT: And your text file is very readable an explains it rather well.

Last edited by purple_pixie; 09-28-2007 at 08:50.
purple_pixie is offline
Twilight Suzuka
bad
Join Date: Jul 2004
Location: CS lab
Old 09-28-2007 , 09:19   Re: String Slicing
Reply With Quote #3

I figured it was well known, but worth posting.
__________________
Twilight Suzuka is offline
Send a message via AIM to Twilight Suzuka Send a message via MSN to Twilight Suzuka
purple_pixie
Veteran Member
Join Date: Jun 2007
Location: Winchester, England
Old 09-28-2007 , 09:22   Re: String Slicing
Reply With Quote #4

I didn't know it, but then I am quite new.

I've never really dealt with pointers before, though.
Though I do understand them.

I've never really seen them because I'm used to Caché which allows for indirection, so it doesn't need pointers.
(that is, referencing a variable (or function) by name, where the name is stored in another variable)

e.g.
PHP Code:
set x="y"
set y="hello"
write @
would write "hello" to the screen.

Much less confusing than pointers.
purple_pixie is offline
Twilight Suzuka
bad
Join Date: Jul 2004
Location: CS lab
Old 09-28-2007 , 09:28   Re: String Slicing
Reply With Quote #5

but also fundamentally less powerful.
__________________
Twilight Suzuka is offline
Send a message via AIM to Twilight Suzuka Send a message via MSN to Twilight Suzuka
purple_pixie
Veteran Member
Join Date: Jun 2007
Location: Winchester, England
Old 09-28-2007 , 11:37   Re: String Slicing
Reply With Quote #6

I assume pointers are pointers directly to memory, then?

So you can pass them between programs and still access the same data?

If that's the case, then pointers pwn indirection.

But I still love indirection ... it also allows for a lot that pointers don't (in the same way)
e.g.
PHP Code:
set x="y+10"
set y=7
write 
@
would, of course, write 17 :-D

Still, someone get us back on-topic ...
purple_pixie is offline
sawce
The null pointer exception error and virtual machine bug
Join Date: Oct 2004
Old 09-29-2007 , 11:49   Re: String Slicing
Reply With Quote #7

The topic is now about bees.
__________________
fyren sucks
sawce is offline
Old 09-29-2007, 16:33
XxAvalanchexX
This message has been deleted by XxAvalanchexX.
Twilight Suzuka
bad
Join Date: Jul 2004
Location: CS lab
Old 09-30-2007 , 02:29   Re: String Slicing
Reply With Quote #8

Oh come on, I posted something useful for once!

Though bees are pretty awesome....
__________________
Twilight Suzuka is offline
Send a message via AIM to Twilight Suzuka Send a message via MSN to Twilight Suzuka
_Master_
Senior Member
Join Date: Dec 2006
Old 09-30-2007 , 14:26   Re: String Slicing
Reply With Quote #9

It's been a while since I looked into amxx source code so I could be wrong about this: doesn't amxx declare the buffer for string manipulations as static?!? If that's true then the main cost would be the actual native call.

Anyways this is usefull if the target position is known, but if you want a subset starting after a certain character then you would still have to use natives ( or not ).
_Master_ is offline
sawce
The null pointer exception error and virtual machine bug
Join Date: Oct 2004
Old 10-01-2007 , 03:19   Re: String Slicing
Reply With Quote #10

Quote:
Originally Posted by _Master_ View Post
It's been a while since I looked into amxx source code so I could be wrong about this: doesn't amxx declare the buffer for string manipulations as static?!?
wut

If you're talking about how the core and modules read a string from a Pawn script, then yes and no, although declaring a heavily used variable static doesn't have as huge of a performance benefit in C as it does with Pawn - the string buffer is declared static internally for convenience.

However, Pawn stores 1 character from each string in one cell. One character in a C-style string is 1 byte long, there are (normally) 4 bytes in one cell - the extra 3 bytes are wasted. The routine to read a Pawn string inside of core or a module has to basically make its own copy of the string, and manipulate it from there.

However, that is assuming the string needs to be passed to a routine expecting a C-style string, a lot of the natives are written to read and change the string as a Pawn style string, so it doesn't have to do the fairly expensive copy back - the inclusion of formatex() was an example of this optimization.
__________________
fyren sucks
sawce is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 03:38.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode