Announcement

Collapse
No announcement yet.

EXE Size

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

  • EXE Size

    Unusually, I'm working on a EXE that will probably reach about 10MB in size.

    Are there any concerns about EXE size in general? I've seen some much larger than 10MB but other than a reduced load time, I've not seen any concerns on the web.

    What's the largest EXE you've every created with PowerBASIC and were there any issues worth mentioning?

  • #2
    Define EXE size for us (well for me!) Gary

    My programs would all be small or middling except sometimes I have huge arrays - how do you relate EXE size to empty huge arrays or full huge arrays?

    Or are you just talking about size on disk?

    I would normally consider breaking a program down into logical bits provided the processing goes through unique stages. SHELLing out is very fast - especially if you are not doing it too often I presume.

    Good discussion

    Kerry
    [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
    Kerry Farmer

    Comment


    • #3
      Hi Kerry!

      The EXE file size.

      Comment


      • #4
        Interesting - so it is not the size of the program in memory? Hmmmm!
        [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
        Kerry Farmer

        Comment


        • #5
          Gary. I am not sure about am idea I had lately and was playing with loading certain files fast. If that is a concern, what I was doing was testing was opening up files located on a server from a workstation and leaving the program running and when I no longer needed them, I was going to kill the program that keep the file open using taskkill. I got the idea from a company selling a program to keep files open on a web server in order to keep the files in cache. If your exe has to be started often, it might sound crazy, but I wonder what would happen if you did something similar with an exe file. The programs I was trying to speed up were written by a third partly and very inefficient on how those programs work with data and it did not help enough for what I was doing. The programs take 2 minutes on files on the server to run the code but on a local drive about 2 seconds. They have to be on the server. But a crazy idea might help in certain conditions where speed is important.
          if that program runs twice a day. That is 4 minutes.
          4 minutes time 220 work days is 880 minutes a year. Which is 14.7 hours a year where somebody is just waiting.
          p purvis

          Comment


          • #6
            One of the sobering facts with modern software is that the code when written properly is usually not all that big but as soon as you start adding resources to the executable it blows out in size very quickly. This is specific to executable file size. Memory footprint is another matter which is usually handled in the code design so that you use the allocated memory as fast and for as short a time as possible. If as Paul mentioned, the data is on a server, you are at the mercy of the data transfer rate of the network server but there are a few tricks here, it is much faster to decompress data that to transfer it across a network so if the data can be highly compressed, it will drop the data transfer time by the compressed size reduction.

            The level of usage matters in that if it is only used occasionally, you can write it in a visual garbage generator because it just does not matter. As the usage goes up the cost in time dictates that you start to make it faster as staff user time is expensive. If something gets used millions of times a day, you start doing things like heavily optimising the code to get the speed up and if its getting data from a server, you start looking at hardware to improve the data transfer rate, optical fibre cabling etc ...

            Usage rate dictates cost and if the usage rate is high enough, code optimisation and hardware reduce the cost against junk software and poor network speed.
            hutch at movsd dot com
            The MASM Forum

            www.masm32.com

            Comment


            • #7
              The biggest EXE file I've produced is around 400k.

              A typical disk drive will run at 100MB/second so your 10MB will only take a fraction of a second to load.

              You have 2GB available under 32 bit Windows operating systems for your exe plus data, (3GB in some cases). So as long as your EXE+data is less than than 2GB and and your PC has 2GB of memory available then you should have no issues with EXE size.

              Comment


              • #8
                On a busy network the loading and shelling can be noticeable. Installing on workstations and pointing only to the data will increase performance.
                I've seen times when a workstation will take much longer than normal to load a program, but that could be anti-virus or other things slowing the transfer.
                https://duckduckgo.com instead of google

                Comment


                • #9
                  Biggest exe I've ever done is about 5 meg. It always runs local, so no issues with load time. Actually, it's loaded almost all the time so nobody would ever notice the load time.

                  Comment


                  • #10
                    I've noticed some strange results with exe's around 1 Gig due to some bmp ressources. Graphics were damaged, crashes are happen.

                    Comment


                    • #11
                      Hi Stefan, Which compiler were you using.
                      p purvis

                      Comment


                      • #12
                        PB10, Paul

                        Comment


                        • #13
                          I've been using the UPX compression tool for a few years. My application has a large # of resources embedded. It works well and I've not had any negative impacts with it. My EXE right out of PB is about 2.5 meg, after UPX is done its about 470K. On my system it takes about 20-25 seconds to do the compress. (Intel i5 @ 3.0 ghz)

                          Comment


                          • #14
                            Stefan:

                            Depending on the number and size of the BMPs bloating the EXE, as well as the way they are used in your program, it may be worth to replace them with JPGs as resources. There is code fast and tight enough to do the conversion back to BMP at running time, without significant time penalty.

                            Comment


                            • #15
                              Manual: Where do I find the code you mentioned?

                              Comment


                              • #16
                                Originally posted by Stefan Kruse View Post
                                Manual: Where do I find the code you mentioned?
                                A quick forum search on jpeg resource returned these two:

                                https://forum.powerbasic.com/forum/u...d-code-from-mm

                                https://forum.powerbasic.com/forum/u...urce-revisited
                                and several others.

                                Comment


                                • #17
                                  Stefan:

                                  This demo code is what I called a "distillate", extracted from several post here about GDI+ functions on the subject, mainly from José Roca. Of course you have to specify your own JPGs.


                                  Code:
                                  'PBCC6/PBWin10 program
                                  #COMPILE EXE
                                  #DIM ALL
                                  #IF %DEF(%PB_CC32)
                                   #CONSOLE OFF
                                  #ENDIF
                                  #DEBUG ERROR OFF
                                  
                                  #RESOURCE RCDATA, #1, "MY_IMAGE_A.JPG"
                                  #RESOURCE RCDATA, #2, "MY_IMAGE_B.JPG"
                                  #RESOURCE RCDATA, #3, "MY_IMAGE_C.JPG"
                                  
                                  %RT_RCDATA           = 10
                                  %GMEM_MOVEABLE       = &H0002
                                  %FALSE               = 0
                                  
                                  TYPE GdiplusStartupInput
                                   GdiplusVersion           AS DWORD
                                   DebugEventCallback       AS DWORD
                                   SuppressBackgroundThread AS LONG
                                   SuppressExternalCodecs   AS LONG
                                  END TYPE
                                  
                                  TYPE GdiplusStartupOutput
                                   NotificationHook         AS DWORD
                                   NotificationUnhook       AS DWORD
                                  END TYPE
                                  
                                  'API Declares
                                  DECLARE FUNCTION FindResourceA LIB "Kernel32.dll" ALIAS "FindResourceA" (BYVAL hInstance AS DWORD, lpName AS ASCIIZ, lpType AS ASCIIZ) AS LONG
                                  DECLARE FUNCTION SizeofResource LIB "Kernel32.dll" ALIAS "SizeofResource" (BYVAL hInstance AS DWORD, BYVAL hResInfo AS DWORD) AS DWORD
                                  DECLARE FUNCTION LockResource LIB "Kernel32.dll" ALIAS "LockResource" (BYVAL hResData AS DWORD) AS DWORD
                                  DECLARE FUNCTION LoadResource LIB "Kernel32.dll" ALIAS "LoadResource" (BYVAL hInstance AS DWORD, BYVAL hResInfo AS DWORD) AS DWORD
                                  DECLARE FUNCTION CreateStreamOnHGlobal LIB "OLE32.DLL" ALIAS "CreateStreamOnHGlobal" (BYVAL hglobal AS DWORD, BYVAL fdeleteonrelease AS DWORD, pstm AS DWORD) AS LONG
                                  
                                  'GDI+ Declares
                                  DECLARE FUNCTION GdiplusStartup LIB "GDIPLUS.DLL" ALIAS "GdiplusStartup" (token AS DWORD, inputbuf AS GdiplusStartupInput, outputbuf AS GdiplusStartupOutput) AS LONG
                                  DECLARE SUB GdiplusShutdown LIB "GDIPLUS.DLL" ALIAS "GdiplusShutdown" (BYVAL token AS DWORD)
                                  DECLARE FUNCTION GdipGetImageDimension LIB "GDIPLUS.DLL" ALIAS "GdipGetImageDimension" (BYVAL nImage AS LONG, nWidth AS SINGLE, Height AS SINGLE) AS LONG
                                  DECLARE FUNCTION GdipCreateFromHDC LIB "GDIPLUS.DLL" ALIAS "GdipCreateFromHDC" (BYVAL hdc AS LONG, graphics AS LONG) AS LONG
                                  DECLARE FUNCTION GdipDisposeImage LIB "GDIPLUS.DLL" ALIAS "GdipDisposeImage" (BYVAL lpImage AS DWORD) AS LONG
                                  DECLARE FUNCTION GdipDrawImageRectI LIB "GDIPLUS.DLL" ALIAS "GdipDrawImageRectI" (BYVAL hgraphics AS DWORD, BYVAL nimage AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG, _
                                                   BYVAL nWidth AS LONG, BYVAL nWeight AS LONG) AS LONG
                                  DECLARE FUNCTION GdipCreateBitmapFromStream LIB "GDIPLUS.DLL" ALIAS "GdipCreateBitmapFromStream" (BYVAL pstream AS DWORD, m_pbitmap AS LONG) AS LONG
                                  DECLARE FUNCTION GdipDeleteGraphics LIB "GDIPLUS.DLL" ALIAS "GdipDeleteGraphics" (BYVAL Graphics AS DWORD) AS LONG
                                  
                                  FUNCTION PBMAIN
                                   LOCAL GDIT???, Inputbuf AS GdiplusStartupInput
                                   LOCAL GF() AS STRINGZ*3, XP&(), YP&(), FR!(), I&
                                   DIM GF(3),XP&(3),YP&(3),FR!(3),hWin???
                                   FR!(1)=1         ' |
                                   FR!(2)=1         ' } Scale factors
                                   FR!(3)=1         ' |
                                   GF(1)="#1"
                                   GF(2)="#2"
                                   GF(3)="#3"
                                   XP&(1)=0         '
                                   YP&(1)=0         '
                                   XP&(2)=0         ' Coordinates of the image's
                                   YP&(2)=0         ' upper left corner within the GW
                                   XP&(3)=0         '
                                   YP&(3)=0         '
                                   GRAPHIC WINDOW NEW " ",150,100,960,720 TO hWin???
                                   GRAPHIC ATTACH hWin???, 0, REDRAW
                                   GRAPHIC CLEAR %WHITE
                                   Inputbuf.GdiplusVersion = 1
                                   IF GdiplusStartup(GDIT???, Inputbuf, $NUL) = 0 THEN
                                    IF GRAPHIC(DC)= 0 THEN EXIT IF
                                    CALL DispResource(GF(1),XP&(1),YP&(1),FR!(1))
                                    SLEEP 10
                                    CALL DispResource(GF(2),XP&(2),YP&(2),FR!(2))
                                    SLEEP 10
                                    CALL DispResource(GF(3),XP&(3),YP&(3),FR!(3))
                                    SLEEP 10
                                    GdiplusShutdown GDIT???
                                   END IF
                                   GRAPHIC WAITKEY$
                                   GRAPHIC WINDOW END
                                  END FUNCTION
                                  
                                  SUB DispResource(GF AS ASCIIZ*3,XP&,YP&,FR!)
                                   LOCAL hResource???, ImageSize???, pResourceData???, m_hBuffer???, pBuffer???
                                   LOCAL pImage???,pGraphics???,HDC???
                                   LOCAL pStream AS DWORD PTR
                                   LOCAL W!, H!
                                   hResource??? = FindResourceA(0,GF, BYVAL %rt_rcdata)
                                   imageSize??? = SizeOfResource(0, hResource)
                                   pResourceData??? = LockResource(LoadResource(0, hResource???))
                                   GLOBALMEM ALLOC imageSize??? TO m_hBuffer???
                                   GLOBALMEM LOCK m_hBuffer??? TO pBuffer???
                                   MEMORY COPY pResourceData???, pBuffer???, imageSize???
                                   CreateStreamOnHGlobal(m_hBuffer???, %false, pStream)
                                   GdipCreateBitmapFromStream(pStream, pImage???)
                                   GdipGetImageDimension(pImage???,W!,H!)
                                   GRAPHIC GET DC TO HDC???
                                   GdipCreateFromHDC(HDC???, pGraphics???)
                                   GdipDrawImageRectI(pGraphics???, pImage???, XP&, YP&, FR!*W!, FR!*H!)
                                   GLOBALMEM FREE m_hBuffer??? TO pBuffer???
                                   GdipDeleteGraphics(pGraphics???)
                                   GdipDisposeImage(pImage???)
                                   SLEEP 90
                                   GRAPHIC REDRAW
                                  END SUB

                                  Comment


                                  • #18
                                    Thanks Manual, I'll give it a chance, but it is still a lot of code to understand and a new source of errors. The size of the exe's is not a huge problem for me because of fast and large ssd's. Most of my programs are in the range of 300m to 600m. Only a handful uses more than 1gig of bmp's, so I load ressources at runtime from ssd with no noticable delays. I'm writing prototyps of video slot machine games for a manufactor in Germany to demonstrate new game ideas I develop.

                                    Comment

                                    Working...
                                    X