Speed of pointers ?

New to FreeBASIC? Post your questions here.
Post Reply
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Speed of pointers ?

Post by Lost Zergling »

This a question about speed, related to internal pointer calculus by the compiler, if I consider the code below (testing) :

Code: Select all

dim titi as any Ptr
dim toto as string Ptr
dim tutu(1) as string
tutu(0) ="T0"
tutu(1) ="T1"

toto=@tutu(0)
Print *toto

Swap titi, toto
Print *CPtr( string Ptr, titi) 
titi+=SizeOf(String) 'Parsing a string Ptr using any Ptr
toto=titi
Print *toto ' Can't use any Ptr to access value
' titi=CPtr( string Ptr, titi) ' has no effect : Any remains byte Ptr
' Print *titi ' => Incomplete type,.. 
Print *CPtr( string Ptr, titi) ' need to specify datatype when accessing
sleep
system
As I plan to code a parser for different datatypes as a property in a typedef, let's consider the 2 options below :

Code: Select all

'Pointer is adapted to parsed the datatype 
Property ArrayExtension.aStep As Byte
    Select Case As Const Datatype
    Case 1 : Str_StepPtr+=INT_StepCursor : Return 1
    Case 2 : Int_StepPtr+=INT_StepCursor : Return 1
    Case 3 : Dbl_StepPtr+=INT_StepCursor : Return 1
    End Select   
    Return 1
End Property
'OR
'In the situation below, no Select Case As Const, but pointer As Any is working at ubyte level
Property ArrayExtension.aStep As Byte
    ANY_StepPtr+=INT_StepCursor   ' Compare to above INT_StepCursor is presiously set to INT_StepCursor*SizeOf(Datatype)
    Return 1
End Property
I wonder wich one fastest. If all pointers are recomputed as byte ptr, second one should run faster, otherwise I don't know.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Speed of pointers ?

Post by caseih »

On Linux with the GCC backend, the CPtr() cast function collapses down to a series of C casts, which are compile-time only, and thus free. In other words CPtr isn't really a function, and thus has no performance cost.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Speed of pointers ?

Post by Lost Zergling »

I see, nice information, thanks. But what I can do for pointers I can't for values.
I don't see a simple syntax avoiding select case for this one :

Code: Select all

Property ArrayExtension.Value As String
    Select Case As Const Datatype
    Case 1 : Return *Str_StepPtr
    Case 2 : Return Str(*Int_StepPtr)
    Case 3 : Return Str(*Dbl_StepPtr)
    End Select
End Property
Nevertheless, it could becomes :

Code: Select all

Property ArrayExtension.Value As String
    Select Case As Const Datatype
    Case 1 : Return *Cptr(String Ptr, Any_StepPtr)
    Case 2 : Return Str(*Cptr(Integer Ptr, Any_StepPtr))
    Case 3 : Return Str(*Cptr(Double Ptr, Any_StepPtr))
    End Select
End Property
with no additional speed cost, so such optimization on parser would theoretically not impact speed when accessing values.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Speed of pointers ?

Post by MrSwiss »

Lost Zergling wrote:But what I can do for pointers I can't for values.
This is a classical: asking the question the wrong way around (logically).
(it's not about: what you can do, it's about: what they can do, for you)
corrected question - wrote: What can I do with pointers, that can't be done with variables?
Answer: e.g. you can use a Type-Ptr to give a whole bunch of variables
to a procedure (one argument).
(instead of: having a whole list of arguments/variables)

This is but one (of many) use(s), of pointers ...
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Speed of pointers ?

Post by caseih »

Lost Zergling wrote:I see, nice information, thanks. But what I can do for pointers I can't for values.
That's right. Pointer casting exists only in the compiler at compile-time. Pointer dereferencing and type coercion is at runtime, however. Except that you want to coerce a value into a string, which isn't ever fast.
with no additional speed cost, so such optimization on parser would theoretically not impact speed when accessing values.
Well you're not accessing values there. You're generating string representations of the values, which is always going to be "slow." There's no way to do this at compile time, and thus you'll always have a performance penalty. You can't compare this (runtime conversion) to compiler pointer casting (compile-time, nothing is converted).

I'm not really sure what you're trying to do here.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Speed of pointers ?

Post by Lost Zergling »

@MrSwiss : you are right. fxm provided me an exemple using Type-Ptr (viewtopic.php?f=17&t=27606&start=70), I need to experiment it. At first sight leads to udt.ArrayAccess[Datatype] vs Select Case As Const Datatype.

@caseih : I'm trying to do (or study the feasibility) of a set of instructions to handle spreadsheet "easy", but nevertheless not too unhealthy in terms of functionality / performance ratio. Moving through strings rather than pointer manipulation is a desirable feature, but it should always be possible for an informed user who prefers to manipulate only pointers to create a property for that purpose.
You can find here some descritption what I may plan to do :
viewtopic.php?f=17&t=27606&start=48
viewtopic.php?f=17&t=27606&start=64
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Speed of pointers ?

Post by caseih »

Given that I can run a full spreadsheet in Javascript these days and it performs well enough, I should think that whatever you do would perform fairly well, even with inefficiencies of string transformation. I wouldn't worry too much about it being slow until you know exactly where your code is spending most of its time and focus there. I tend to spend way too much time thinking about the "right" way to do something, rather than just writing code and making an attempt.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Speed of pointers ?

Post by MrSwiss »

Another example, which highlights the advantage of pointer vs. variable:
  • with variables only, one must create a Union, to get at its internal
    UBytes of a ULong (as a helper structure)
  • with CPtr() one acceses them directly
Assume: get color from WIN-API, which is to be used in FB's GFX that features
inverted blue/red color positions (inside a ULong) ...
Which is, what the code has to accomplish, as painless and fast as possible.
(compare the amount of code for both versions):

Code: Select all

' for WIN-API to FB_GFX and, vice versa
Function BGR_RGB_U( _                   ' only 24/32 bit color 
    ByVal clr   As ULong _              ' blue and red exchange _ 
    ) As ULong                          ' aka: FB to WIN or WIN to FB
    Union UL_UB                         ' needed to get at the UBytes _
        As ULong      ul                ' inside a ULong, if we don't have _
        Type                            ' pointer cast for simplification
            As UByte  ub0, ub1, ub2, ub3
        End Type
    End Union

    Dim As UL_UB    u

    u.ul = clr
    ' from here on: more or less the same as below 
    Swap u.ub0, u.ub2
    Return u.ul
End Function

Function BGR_RGB( _                     ' dito (as above)
    ByVal clr   As ULong _
    ) As ULong
    Swap CPtr(UByte Ptr, @clr)[0], _    ' CPtr() use (direct to the UBytes)
         CPtr(UByte Ptr, @clr)[2]
    Return clr 
End Function


Const As ULong  red = &hFF0000ul, blue = &h0000FFul

Print "original", "BGR_RGB_U", "BGR_RGB", "action"
Print "using:", "Union", "CPtr()"
Print String(53, "-")

Print Hex(red, 6),Hex(BGR_RGB_U(red), 6), _
      Hex(BGR_RGB(red), 6), "red to blue"
Print Hex(blue, 6),Hex(BGR_RGB_U(blue), 6), _
      Hex(BGR_RGB(blue), 6), "blue to red"

Locate CsrLin + 2
Print "... done ... ";

Sleep
The main point here, is not so much, can it be done, but rather, how much
effort is required, to do so ... hint: I'd opt for the CPtr() version.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Speed of pointers ?

Post by Lost Zergling »

The parser is intended for the user to be able to write his code or his own functions, and identically to the internal functions. In the logic of the tool, the parser has the highest level of priority because the whole tool will be built around it. The parser that seems the fastest is the increment of a pointer (ANY_StepPtr + = INT_StepCursor seems more relevant than myUdt.Array + = INT_StepCursor). This consideration seems to favor the use of the Cptr () solution to access the values. In the given LZAE example, you must pass the properties (SetCursor) in ByRef, otherwise you can only test the parse on strings. By staying in the consistency and logic of the tool, it is not abnormal that the Value property returns a string type, the associated list engine working almost exclusively on this type of data. The user not wishing a slowdown because of the transformation into a string can create its own properties DBL_value and so on easily. The tool is not thought at the base to work on arrays of UDT. For the search and unique, the tool does not need to return an array, the most relevant would be to return a list and it will be available in memory(*). I can already imagine easily, however, there are still lots of details to code, test and develop.
(*): coding additional functions list to array (or vice-versa) is trivial further more as considered array is single vector and thus would be required only when array (or list) is really needed for functional features or speed improvements.
Addendum : I'll do it. I started typing in it. Due to the choice of not using Define, neither macro and so on, and also because of the programming style, the code is of a rare inelegance and ugliness.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Speed of pointers ?

Post by Lost Zergling »

Concretely, and to summarize the situation: there is no generic way to access the first element of a table without having to know in advance the number of dimensions. The syntax does not allow it and the syntax control prevents users from doing this. All the useful information is accessible in the "descriptor", but apparently there is also no consensual generic way to access it, even read access. In addition, the arrays are isolated and it is not possible to pass them by reference(*) or to return them. However, it is quite easy to find useful information by algorithmic with Ubound and Lbound. I think to put aside this part of the syntax automation. So, instead of coding something like this :
Dim aext As ArrayExtension
aext.Set (MyArray)
The developer will write (if we need the dimensions structure, it can be concatenate in string same way):
Dim aext As ArrayExtension : Dim As Integer NbElements=1, Iterate
For Iterate = 1 TB Ubound (MyArray, 0): NbElements=NbElements*(Ubound (MyArray,Iterate)-Lound (MyArray,Iterate)+1): Next Iterate
aext.SetElements(NbElements)
aext.Set(MyArray(Lbound(1),... Lbound(n) ))
There are three lines of code to copy paste, the name of the array to change and the number of dimensions to specify to access the first element. Developers who wants to use array functions will be able doing it. This is not very pleasant because it is unnecessarily heavy and more code then depend entirely on the reliability of the input parameters. But it's not too serious issue because this syntax is only for setting up.
The solution that I envision is that there is none and it is easier to adapt (meanwhile better) kinematics instructions to this way of doing. Another advantage is that it remains completely generic with the original specifications of the language.
Addendum : of course, ones could imagine something like that :
MyMacro_SET(MyArray, NbElements, FirstElement Ptr) or MyMacro_SET(MyArray,aext) wich would be in user context a syntactic extension, but at what cost ?
(Thus, this can be added later as a level-below over-implementation till it embbed naturaly some of the missing exception handling).
(*) : ERRATUM : overloading with arrays passed ByRef is ok.
Post Reply