Announcement

Collapse
No announcement yet.

Byval/ByRef in DECLAREs

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #21
    Originally posted by Tim Lakinir View Post
    BYREF is the default in PB while BYVAL is treated as inefficient under CALL help
    large parameters BYVAL are stated to be inefficient.



    =========================
    https://camcopng.com
    =========================

    Comment


      #22
      Put aside the folklore and look at the code.
      Code:
       ' RegisterClassEx ByVal(VarPtr(wcex))
      
       ' 002011B8 8D9D30FFFFFF lea ebx,[ebp-0D0h]
       ' 002011BE 53 push ebx
       ' 002011BF FF1510522000 call dword ptr [RegisterClassExA]
       ' 002011C5 D96DF0 fldcw [ebp-10h]
      
       ' RegisterClassEx wcex
      
       ' 002011B8 8D9D30FFFFFF lea ebx,[ebp-0D0h]
       ' 002011BE 53 push ebx
       ' 002011BF FF1510522000 call dword ptr [RegisterClassExA]
       ' 002011C5 D96DF0 fldcw [ebp-10h]
      Spot the difference, there ain't any.
      hutch at movsd dot com
      The MASM Forum - SLL Modules and PB Libraries

      http://www.masm32.com/board/index.php?board=69.0

      Comment


        #23
        Hi Steve,

        what is your easiest method to dissasemble pb code?

        eg:

        FOR x = 1 TO 999
        IF LEN(s$) THEN
        ...
        END IF
        NEXT

        vs

        i = LEN(s$)
        FOR x = 1 TO 999
        IF i THEN
        ...
        END IF
        NEXT

        was my resolved myth

        Comment


          #24
          Denis,

          Much the same as anyone else, get a disassembler for 32 bit and disassemble the binary file you are interested in.

          Now a trick to identify a statement within the disassembly is to mark before and after the statement with a sequence of known assembler statements. I use the following.
          Code:
          mov eax, eax
          mov eax, eax
          mov eax, eax
          mov eax, eax
          mov eax, eax
          mov eax, eax
          
          ' your code to disassemble
          
          mov eax, eax
          mov eax, eax
          mov eax, eax
          mov eax, eax
          mov eax, eax
          mov eax, eax
          Then look in the disassembly for the before and after sequences of mov eax, eax.

          Be warned the basic code is a lot more complex than many other languages and for what appears to be a simple statement will often have branching well away from the isolated statement.
          hutch at movsd dot com
          The MASM Forum - SLL Modules and PB Libraries

          http://www.masm32.com/board/index.php?board=69.0

          Comment


            #25
            Originally posted by Stuart McLachlan View Post

            But note that under CALL it also says:
            "Try to avoid passing large items BYVAL, as it's terribly inefficient, and there is a maximum size limit of 64 Kb for a given parameter list. Arrays cannot be passed BYVAL."

            Well, that's quite an awkward and very unspecific statement. Something I wouldn't expect for a technical manual.

            What does "inefficient" exactly mean in that regard?

            And TBH, I prefer code maintainability and readability over efficiencies. Because the former saves yourself and your users from introducing bugs to your software, while the latter these days is often only measured in seconds or even milliseconds, something a) most users won't recognize and b) may very well [i]also[I] happen due to other circumstances and not caused by your software, e.g. overall high system load, network bottlenecks, interfering software (AV).

            Comment


              #26
              > What does "inefficient" exactly mean

              Generally speaking, the under-the-hood code for BYREF is less complex than BYVAL or BYCOPY. Fewer steps. For small data items like individual numerics it makes very little difference. For large items like strings and UDTs, the difference becomes important if you need to get as much speed as possible from a section of PB code.
              "Not my circus, not my monkeys."

              Comment


                #27
                For large items like strings and UDTs, the difference becomes important if you need to get as much speed as possible from a section of PB code.
                And for these things, consider NOT using a procedure and passing parameters... instead put the code inline and use MACROs for re-usability(*).

                If it hurts when you do something, then don't do that!

                MCM
                * and don't whine about the size of your executable!
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                  #28
                  Originally posted by Eric Pearson View Post
                  For large items like strings and UDTs, the difference becomes important if you need to get as much speed as possible from a section of PB code.
                  Again: what does "important" mean? It's as specific as "inefficient".

                  Start talking numbers, because what's "important" to someone is negligible to someone else.

                  Comment


                    #29
                    I'll whip up an example, but not right now.
                    "Not my circus, not my monkeys."

                    Comment


                      #30
                      Spot the difference, there ain't any.
                      You know, the compiler might be smart enough to pick that up and make it "no difference."

                      After all, BYVAL VARPTR (anything) = BYREF (same anything)

                      That is, you have not made an invalid comparison in this case.

                      Also, as I said before, it's not just the code at the point of call, it's the usage of the argument in the receiving procedure which Impacts the performance and resource utilization.

                      MCM
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                        #31
                        Just going back to the direct question which started the 2021 portion of this thread, (Post 7)

                        Hi All, I wonder which declare works faster and which saves more memory for BYVAL and BYREF ?
                        If you are speaking of the DECLARE statement , changing that statement cannot do anything except cause your program to fail . To use any external procedure, the DECLARE statement must match the way said external procedure is coded in the absence of point-of-call overrides.

                        Ditto for using a BYVAL, BYREF or BYCOPY override at the point of call: whatever you do at the point of call must match the way the external procedure is coded, in that the use of an override at the point of call now ignores the DECLARE statement's individual arguments' call method (small "m" not to be confused with METHOD in COM programming).

                        I know that is kind of implied by all the responses you got but I cannot find it stated explicitly.

                        MCM
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                          #32
                          > After all, BYVAL VARPTR (anything) = BYREF (same anything)

                          I was hoping that Tim would not be further mislead, basic has for a long time had BYREF available for its prototypes which means no more that pass the ADDRESS of a variable rather than its content. PB also passes a dynamic string address BYREF. Now with PB prototypes which is the trigger for the original question, if an argument in a function call is not specified as BYVAL, then it is BYREF by default so if you code a function call and it squarks at you, as usual you have to go to the main include file and see how the prototype was written. Not being a fan of PB prototypes, I tend to create new ones if they annoy me enough.
                          hutch at movsd dot com
                          The MASM Forum - SLL Modules and PB Libraries

                          http://www.masm32.com/board/index.php?board=69.0

                          Comment


                            #33
                            My fear was, OP may have thought that changing a DECLARE statement can actually change the performance of an external function.

                            You may think that thought naive, but you have a lot more experience than many of our members, including all the 'lurkers' who do not themselves post but do read.

                            Sometimes we, um, "veteran" types forget just how much we had to learn before we knew enough to think we knew what we needed to know..

                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                              #34
                              ByVal Long is no faster than (ByRef) Long (when not changing the long variable), but is so for Single, Double, or Quad?

                              And that ByVal String takes up space on the stack. Setting aside taking up space on the stack, is ByVal String any faster than (ByRef) String (when not changing the string variable)?
                              Last edited by Mark Hunter; 17 Apr 2021, 03:56 PM.
                              Algorithms - interesting mathematical techniques with program code included.

                              Comment


                                #35
                                BYVAL vs BYREF . BYVAL has to get the value which is stored by address to make the call. the using routine has to get the value - IF NEEDED - when the address is passed.

                                So you cannot say one is faster than the other.. it depends on the using ("passed to") procedure.. FOR NUMERICS.

                                (Fixed or NTS) Strings and UDTs are different, as all the bytes of the structure must be copied to the stack at the time of the call if you pass BYVAL Of course when you pass a UDT BYVAL the values of the members are now local to the using routine but I don't recall ever using ALL the members' values of a passed UDT. So "how used" is once again in the picture.

                                BYVAL and BYREF *dynamic* strings ... same as numerics as they are passed as a 32-bit integer... depends on the use; except I am pretty sure PB creates a duplicate string and string data, which takes time... and then more time to destroy it on return from the call. so BYVAL <dynamic string> may be a real loser because of the additional string creation/destruction.

                                If you really want to try to tune performance based on procedure argument calling method BYVAL vs BYREF.... instead write a MACRO and use that inline. Now there is never a need to "pass" anything. Of course, it makes your executable (EXE, DLL, or SLL ) larger, so once again we have proven there is no such thing as a free lunch.

                                Personally? I have always used BYREF except when I have a good reason to pass BYVAL or BYCOPY. I also consider BYVAL/BYREF/BYCOPY a silly place to look for performance improvement... which is far more controlled by design and basic programming techniques such as avoiding both mixed-mode arithmetic and string operations, using pointer variables and avoiding doing things repetitively inside a loop when you can do them ONCE outside a loop instead.

                                YMMV.

                                MCM
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment

                                Working...
                                X
                                😀
                                🥰
                                🤢
                                😎
                                😡
                                👍
                                👎