Using a bank instead of a string

Blitz3D Forums/Blitz3D Programming/Using a bank instead of a string

_33(Posted 2007) [#1]
Ln = CreateBank (80)
For i = 0 To 78
   PokeByte Ln, i, Rnd(32,127)
Next

PokeByte Ln,79,0

Print Ln
WaitKey()


So, here I tried to print the text in the bank, but obviously it doesn't work as simple as that since it prints the address of the bank. It could be undoable, but who doesn't try never knows. What I want to do eventually is send the text in a bank instead of sending a string, as I am playing with bank data. I don't want to make strings from my banks, it's too slow for the task at hand.

Here's a link to a general Blitz3d benchmark program: http://www.blitzbasic.com/codearcs/codearcs.php?code=1998#comments

Thanks.


cyberyoyo(Posted 2007) [#2]
something like
for i=0 to 78
    write chr$(peekbyte ln,i)
next


should work


_33(Posted 2007) [#3]
Well, the whole idea is to avoid string commands, as they take 250 to 800 ns each... So definately I want to avoid turning a peek into a chr$. Might as well just deal with a string in such a case.


John J.(Posted 2007) [#4]
Well, the whole idea is to avoid string commands, as they take 250 to 800 ns each... So definately I want to avoic turning a peek into a chr$. Might as well just deal with a string in such a case.

If performance is that critical, maybe you should write this section of code in C, and interface it with Blitz3D as a userlib. Because I don't think Blitz3D is capable of what you're trying to achieve.


_33(Posted 2007) [#5]
If performance is that critical, maybe you should write this section of code in C, and interface it with Blitz3D as a userlib. Because I don't think Blitz3D is capable of what you're trying to achieve.



But it's puzzling! What does blitz consider as a string? Can't a bank be considered a string? Without any data conversion? It doesn't need data conversion does it? Or maybe I need to trick blitz into thinkig the bank is a string...

hmmm...(!)


Subirenihil(Posted 2007) [#6]
The data will be converted to a string at some point, so I don't understand your reluctance to write a small conversion process yourself.

for i=0 to 78
    write chr$(peekbyte ln,i)
next



_33(Posted 2007) [#7]
Subirenihil, if you don't understand the subject at hand, why reply? I am looking for an ALTERNATIVE of chr$, NOT chr$. Basically it's almost hacking blitz what I'm asking.


_33(Posted 2007) [#8]
John J., actually I don't know if you remember some other languages that let you redefine something. Say you got the COBOL language. In COBOL, you can redefine an allocated zone into something different. That way, you can either treat it as say (in cobol mind you) a 999v99, or as XXXXX. Meaning either 3 digits + virtual dot + 2 digits, or 5 characters. Basically I would like to do that with strings. To be able to redefine them as a bank, or vice versa. Reason for this is because I don't know the address of the string. If I had the start address of the string, then I suppose I could peek and poke from it what I need, and avoid using heavy instructions such as ASC and CHR, but still keep the properties of a string.

LINK supplied: http://publib.boulder.ibm.com/infocenter/cicsts/v3r1/index.jsp?topic=/com.ibm.cics.vt.doc/cvtug/topics/cvtug_redefines_clause.htm


Kev(Posted 2007) [#9]
_33 use the api CallWindowProc() and pass the bank and return the string in eax

decls
.lib "user32.dll"
API_CallWindowProc$(asmbank*,param1*,param2%,param3%,param4%):"CallWindowProcA"


example

asmbank = CreateBank(6)
PokeByte asmbank,0,$8B	; MOV EAX,DWORD PTR SS:[ESP+4]
PokeByte asmbank,1,$44
PokeByte asmbank,2,$24
PokeByte asmbank,3,$04

PokeByte asmbank,4,$C3	; RET

str_bank = CreateBank(256)
PokeByte str_bank,0,Asc("T")
PokeByte str_bank,1,Asc("E")
PokeByte str_bank,2,Asc("S")
PokeByte str_bank,3,Asc("T")
PokeByte str_bank,4,0

a$ = API_CallWindowProc(asmbank,str_bank,0,0,0)
Print a$
MouseWait
End



kev


Who was John Galt?(Posted 2007) [#10]
Cool example! Will DEP not complain if it's enabled?


_33(Posted 2007) [#11]
How to call your own machine language subroutine, the Kev way. I like that! You've got some heck of a skill right there. Thanks Kev, and of course I knew I posted this on the right forum. Very appreciated. I'll check the performance of that, see what's the benchmark, without the string assignment, just the CallWindowProc.

But as a note, the 4 PokeByte instructions that you just mentionned about in the example will take total a total around 2000ns of cpu processing time. The same type of thing could have been done with PokeInt str_bank,0,$54455354 and PokeByte str_bank,4,0 for a total of around 20 ns total cpu processing time. But I think you know this, and it was just a note for the crowd.


Kev(Posted 2007) [#12]
Asc() for the example is a easy way to display what is being poked into the bank.

A side note when API_CallWindowProc() is called param1,2,3,4 are pushed onto the stack hence we have access to 4 memory address in any one call.

kev


_33(Posted 2007) [#13]
Kev, a question. I had this before in user32:
api_CallWindowProc% (lpPrevWndFunc%, hWnd%, Msg%, wParam%, lParam%) : "CallWindowProcA" 


Do you think it was a placeholder, because I'll replace it with your call.

Thanks.


Kev(Posted 2007) [#14]
_33

the bb calling conversion for .dll calls require's '*' when passing a banks address, using '%' passes an int value. we need the banks address for API_CallWindowProc().

really it depends on what you want to pass to your custom winproc. although asmbank is aways a bank address and written using asm bytecode.

kev


_33(Posted 2007) [#15]
OK Kev, I've done some benchmarks, and the results are negative. Blitz does it the faster way.

On my machine (Dual core Athlon 2.8ghz DDR433):

L$=M$: 40.0 ns
L$=M$+S$: 250.0 ns
L$=Left$(M$,SQ): 90.0 ns
L$=Right$(M$,SQ): 90.0 ns
L$=Chr$(SYM): 160.0 ns
L$=Mid$(M$,SPOS,SQ): 210.0 ns
L$=STRINGF$(M$): 100.0 ns
L$=sm$(spos): 35.0 ns
a$ = API_CallWindowProc(asmbank,str_bank,0,0,0): 676.0 ns

I don't think blitz is called blitz for nothing, but if it's possible to have faster string handling, I'll take it.


Damien Sturdy(Posted 2007) [#16]
What exactly is this for?


_33(Posted 2007) [#17]
Alternative for faster string handling.


Trader3564(Posted 2007) [#18]
wow, so more code is faster execution?


b32(Posted 2007) [#19]
Sometimes it is:



Kev(Posted 2007) [#20]
i done no speed testing _33, the example provides a way to do what you asked but not fast enough :P

@b32. intresting example.


_33(Posted 2007) [#21]
I suppose calling any windows API is incredibly slow... I have no clue if Vista is faster thoe, but I suspect not by much if it is.

Kev, do you know any other way to launch machine language code than with a windows API? I've tought of a small DLL that could take machine code and execute it, but I'm not skilled enough to do that! Specially this sort of thing. But funny enouhg, I find it easier to do machine language since it's got so little syntax to it. I could probably hack in some SSE, SSE2 code if I had the opportunity. So I can definately imagine a DLL that enables machine language calls from blitz and having some special speedy stuff going on for those special places that need the speed.


Who was John Galt?(Posted 2007) [#22]
You haven't really described what you're trying to achieve with this as a whole.

A$="Hello" will be faster than anything you can come up with because it's a just data in the exe...it will exist before any speed test timers are kicked off. Poking into banks involves moving data from one place to the other, ie: Real execution time.


_33(Posted 2007) [#23]
S$ = "Hello": 190.0 ns (nanoseconds taken by the cpu)

Moving "Hello" in a data bank, takes aproximately the same time that takes to do a PokeInt, which is around 8 ns (nanoseconds), meaning more than 10 times faster than the standard string assignment.

b32: the 2 ms difference is because you're also taking in acount the For...Next loop which will also take some cpu time.


Who was John Galt?(Posted 2007) [#24]
What code are you using to do this benchmark?


cyberyoyo(Posted 2007) [#25]
There are two slow down when manipulating strings: 1.actual string creation and manipulation and 2.string display

1.I don't see why you'd need to speed up string manipulation unless you make a very string intensive code such as a database for example. but in most case you'd better have to use proper libraries (for database) or replace string by other types of shortcuts.

2.String display, IMO that's where you should try to gain some time.

But if you don't tell us what the program is about it's difficult to work out a solution.


_33(Posted 2007) [#26]
OK guys, time out. Kev gave me pretty much the answer. Now you can leave this one alone, unless you have a real solution.

Thanks.


cyberyoyo(Posted 2007) [#27]
At least we know when not to write the adress of a bank lol.


_33(Posted 2007) [#28]
Well the real question was: "Can we do string manipulation faster than how blitz does it". Meaning that there could be an alternate method. But obviously it's getting a little out of hand. So, as a note, if people want to know what I'm doing, they can always consult my worklog, which is about my main project. I've posted 2 screenshots also in the Gallery.

Cheers.


John J.(Posted 2007) [#29]
Sorry for not responding, I forgot about this thread :)

John J., actually I don't know if you remember some other languages that let you redefine something. Say you got the COBOL language. In COBOL, you can redefine an allocated zone into something different.

Of course. In C++, this is called casting. You can convert just about anything to just about anything else with a simple cast. Unfortunately, Blitz doesn't support this (BlitzMax probably does) natively, and only has some basic string/int/etc. conversion (nothing to do with banks).

So even if Blitz does store strings in the same format as your banks, there's really no way to convert between the two quickly.

Well the real question was: "Can we do string manipulation faster than how blitz does it". Meaning that there could be an alternate method.

As far as I know, this isn't possible in BlitzBasic. A more flexible language like BlitzMax or C++ can, but not BlitzBasic.

But, what exactly is it you're trying to process that needs to be so fast? In MaXML 2.0, I read an entire XML file into a bank and peek values out, which is very fast (just like C strings). As the file is parsed, the appropriate pieces of information are converted back into strings and placed in their data structures. There are many ways you can do fast string processing in Blitz, but it's hard to tell what method is best without knowing just what needs to be done.

Unfortunately, Blitz may not be capable of the speeds you want, from what it sounds like. If speed is that critical, I'd write a DLL in BlitzMax or C++ and shift the processing load over to that.

P.S. Probably the reason Blitz strings are so slow in comparison to banks is simply because strings are not fixed in length. When you add 3 characters to a 100 character string, for example, you're not just writing 3 characters to memory, but actually:

1. Allocating space in memory for 103 characters
2. Writing 100 + 3 characters to the new memory area
3. Deallocate the old 100 characters

I'm not sure about this, but basically you can't easily "resize" a block of memory without copying it's contents into a new larger block and destroying the old.

When you know the maximum size of your strings, you can use more efficient string methods, like C strings, or in your case, Banks.


_33(Posted 2007) [#30]
Well, I'll convert my CSI handling to banks soon. THAT is my main concern. It's too slow for handling escape code sequence like in ANSI. It works thoe, 100% ideal output, just that with MID$, LEFT$, STRING$ etc etc, it's too damn slow for a terminal emulator.

http://www.blitzbasic.com/logs/userlog.php?user=10319&log=1460

YOu can see on the screenshot in my worklog, the bottom left test pattern takes roughly a full second to display. meaning a full second that it's shuffling with MID$, ASC, CHR$... But my processor is fast, it's more a case of inefficient code. By using a BANK for my CSI, i'll cut down the time by at least 1000%!