Mirage Source http://web.miragesource.net/forums/ |
|
Major Basic Opimizations http://web.miragesource.net/forums/viewtopic.php?f=210&t=777 |
Page 1 of 1 |
Author: | William [ Wed Nov 29, 2006 10:49 pm ] |
Post subject: | Major Basic Opimizations |
Introduction I know we all wants our projects optmized. I also know there are many different tutorials for this, but this one will be the biggest. It might take some time to go through it by I think it's worth it. Note I do not take credit from anything, since it's mostly collected from the web. 1. Optimize for memory 2. Optimize for speed 3. Save memory 1. Optimize for memory Get rid of dead code Dead code means unnecessary, inoperative code that can be removed. Dead code includes functions and sub-programs that are never called, properties that are never read or written, constants and enums that are never referenced. Dead variables are ones that are never read - even if they've been given a value. User-defined types can also be dead, and there may be a lot of extra API declarations. Even whole files can sometimes be completely unnecessary. Dead code leads to excessive memory use, slower execucation, larger .exe files, higher maintenance effort and errors. That's why it's important to clean your projects by removal of dead code. Avoid fixed-length Strings Fixed-length strings generally occupy more memory than variable-length ones. The problem is worse if you have to reserve lots of space for long strings in your fixed-length string variables. If you're planning to migrate to VB.NET, then you have one more reason why not to use fixed-length strings. VB.NET doesn't support them natively. You get better performance with variable-length strings. Avoid static variables Static variables are those that reside in the memory for the whole execution time. The opposite of static variables are dynamic variables. Dynamic variables are procedure-level variables that are created when the procedure is entered, and destroyed when the procedure ends. How do I know which variables are static or dynamic? Static Variables 1. Variables declared in the (declarations) section. 2. Local variables declared with the Static keyword. Static Arrays 1. Arrays declared with subscripts in the (declarations) section. Example: Dim MyArray(1 To 45) 2. Local arrays declared with the Static keyword. Dynamic Variables Local variables. Dynamic Arrays 1. Arrays declared without subscripts in the (declarations) section. Example: Dim MyArray() 2. Local arrays declared with the Dim or ReDim keywords. Local are those variables and arrays that are declared inside a procedure. So why should you avoid static local variables? Static variables are slower and consume memory. It is better to use normal, dynamic local variables. If you really need a static local variable, use a private module-level variable instead. There is a drawback with this, though. You should keep other procedures from using the same variable to avoid unwanted side-effects. Reclaim memory after use If you are using static variables, it's important to reclaim the memory they occupied when you don't need the variables any more. With dynamic variables memory isn't so much of a problem, because they are destroyed when the procedure ends. This is how you can reclaim thhe memory: Type of variable...........|.......Code to reclaim occupied space Variable-length String...|.......MyString = vbNullString Variant.......................|........MyVariant = Empty Form..........................|........Unload MyForm Object........................|........Set MyObjectVariable = Nothing Reclaim memory from arrays Arrays are often memory-hungry. This applies especially to static arrays, whose size is fixed for the lifetime of the program. Dynamic arrays are better for memory optimizations, because they can be resized. However, some memory optimization can be applied to both array types. One way to reclaim space occupied by an array is to clear all its elements one by one as shown above. Another way is to use Erase or ReDim.
VB's default data type is Variant. All variables that don't have any other type are implicit Variants. Avoid variants when possible. They are slow, and they consume memory. If you use variant instead of, say, integer you waste 14 bytes of memory. This can be significant in a large project. Integers are much faster than variants. This is true particularly in For..Next loops. Use Option Explicit to force declaration of your variables. This helps you to get rid of unnecessary variants. Aivosto Project Analyzer can help you to ensure properly typed variables. It can list the implicit Variants and missing Option Explicit statements for you. Typing your variables is a very good habit and a sign of professional development. Memory optimizations with graphics Graphics may use a lot of memory and also slow your program down. Here are some easy tips to avoid that. 1. Reclaim graphics memory with LoadPicture() and Cls. You can also set the Picture property to Nothing (VB 4.0 and later). 2. Use Image controls instead of PictureBoxes. 3. Use RLE, GIF, JPG, and WMF picture formats instead of BMPs. If possible, try to reduce the number of colors in your pictures. 4. Load a picture only once. If you need to display one picture in several places, you can just assign it from one control to another with this code: MyGraph.Picture = OldGraph.Picture Doing this will save the picture only once in your executable file, but you may use it on many controls. 5. Set AutoRedraw = False. If it's True, VB will create an AutoRedraw image that consumes memory. 2. Optimize for speed The empty string Is the "" expression often found in your code? Beware! So many CPU cycles are wasted for such a string! Testing and assigning empty strings is an easy place for optimization. Checking for empty string It's often necessary to test for an empty string. The usual ways are these: Code: If Text$ = "" Then However, VB executes the following equivalent statements much faster.If Text$ <> "" Then Code: If LenB(Text$) = 0 Then If LenB(Text$) <> 0 Then The replacement is essentially risk-free. Your code executes the same as before, only faster. VB's implementation of LenB is fast. LenB is the byte equivalent of Len. Len is actually implemented as LenB\2. That makes LenB is faster than Len, so you should use it where possible. VB3 and VB.NET don't have the LenB alternative, in these languages you should use Len. Note that we use the <> operator, not >. <> simply tests for inequality, while > tests more. As Len/LenB never return a negative number, we can safely use this test. Assigning an empty string to a variable This is the usual way to clear a string variable. Text$ = ""What a waste! First of all, the string "" takes 6 bytes of RAM each time you use it. Consider the alternative: Code: Text$ = vbNullString No variants It's a simple thing but often overlooked. All variables, parameters and functions should have a defined data type. If the data is a string, then the data type should be defined as string. If you don't give a data type, you're using a variant. The variant data type has its uses but not in string processing. A variant means performance loss in most cases. So add those Option Explicit statements now and Dim all variables with a decent data type. Review your functions and ensure that they define a return data type. Dollars that make your program run faster The following functions unoptimal if you're using them on strings. Code: Left(), Mid(), Right(), Chr(), ChrW() UCase(), LCase(), LTrim(), RTrim(), Trim(), Space(), String(), Format(), Hex(), Oct(), Str(), ErrorThese are the dreaded variant functions. They take a variant, they return a variant. These functions are OK to use if you're processing variants. This is the case in database programming, where your input may contain Null values. So what's all that variant stuff in string processing? It's fat. If you're dealing with strings, forget about the variants. Use the string versions instead: Code: Left$(), Mid$(), Right$(), Chr$(), ChrW$() UCase$(), LCase$(), LTrim$(), RTrim$(), Trim$(), Space$(), String$(), Format$(), Hex$(), Oct$(), Str$(), Error$ Use Private Whenever possible, use the keyword Private. This will make your procedures and variables accessible inside the same module only. The advantage is increased modularity in your code. Code: Private MyVariable As Integer Private Sub MyProcedure() Optimize display speed Often it's important how fast your application appears to run, even if the the actual speed isn't that high. Some ways to speed up display speed: 1. Set ClipControls property to False. 2. Use Image instead of PictureBox, and Label instead of TextBox, if possible. 3. Hide controls when setting properties. This prohibits multiple repaints. 4. Keep a form hidded but loaded if you need to display it fast. The drawback of this method is that it consumes some memory. 5. Use background processing for longer runs. You can achieve background processing with appropriately placed DoEvents. A good place to put DoEvents is inside time-consuming loops. This needs some consideration, because the user might click some buttons, for example, and your program must know what the user is allowed to do when the background process is running. Set flags like Processing=True and check them in appropriate places. 6. Use progress indicators. 7. Pre-load data you will need later. For example, you can load the contents of a database table into an array for faster access. 8. Use Show in Form_Load event. 9. Simplify your startup form, or use a splash screen. 3. Save memory Clear old memory before requesting more Your application might temporarily require 2x the memory it actually uses. Consider the following code snippet: Pic = LoadPicture("abc.bmp") ' Load a picture from a file Form1.Picture = Pic ' Display the new pictureWhat's wrong here? You may be holding two pictures in the memory at the same time! You are possibly displaying an old picture on Form1 while loading the new one. If the pictures are large, this can slow down your app quite a bit as it suddenly needs to allocate lots of new RAM. If you're running low on RAM, the system may need to access the swap file, which is slow. The solution is to unload the old picture first. This way you don't need the RAM for that picture any more and the system will probably allocate the freed memory for the new picture. This might cause a flashing effect in the user interface, though, before you get the new picture displayed. Clear your globals Global variables are nasty as it's so easy to forget to clear them. Once your software keeps running never clearing its globals, you end up carrying old data for no use. For Speed
Here are some more deeper information concerning a few of the above examples:
Hope you enjoyed the reading, I will continue updating it. |
Author: | Lea [ Thu Nov 30, 2006 12:54 am ] |
Post subject: | |
A lot of good information here. I'm going to copy it to the Knowledge Base. However, I disagree with this: Quote: Avoid fixed-length Strings
Fixed-length strings generally occupy more memory than variable-length ones. The problem is worse if you have to reserve lots of space for long strings in your fixed-length string variables. If you're planning to migrate to VB.NET, then you have one more reason why not to use fixed-length strings. VB.NET doesn't support them natively. You get better performance with variable-length strings. First I must stress that a "String" as we know it, is simply a pointer to a byte array. As I understand it, Fixed Length strings are pointers to byte arrays of fixed length n, where n is the "* n" part in the declaration. So for Code: Dim FixedString as String * 4 Fixed String = "four" LenB(FixedString) would be 4, four bytes of memory. However, the equivelant code Code: Dim DynamicString as String
DynamicString = "four" setting the dynamic string byte array, first you need to resize the byte array to the correct size. Redim Array(3) then put the characters in, making it slower. Next, Dynamic Strings in Visual Basic are stored in memory as Unicode, which means a string "Four" will be stored using 8 bytes of memory: Like this: "0F0O0U0R" So you're already using double the ammount of memory than a fixed length string uses, although LenB still returns the same length (it does right? Test it ) On top of that, VB stores a 20 byte header for each string. So the length of string "Four" becomes 28 bytes. Much much more than the 4 bytes it takes to store as a fixed-length string. Ta~ |
Author: | Verrigan [ Thu Nov 30, 2006 7:02 am ] |
Post subject: | |
Code: Public Sub Test() Dim teststr As String * 256 Dim teststr2 As String teststr2 = String(256, " ") Debug.Print LenB(teststr) Debug.Print LenB(teststr2) End Sub This results in the following being printed to the debug window: Quote: 512 512 So.. LenB returns the memory in bytes (not including the overhead) of the string.. Fixed-Length strings only use up the amount of bytes you fix them at.. (In this case, 512).. Variable length strings use 10 bytes + the number of bytes for the string.. (522, for ours..) Though.. MSDN says 'length of string', yet it is actually length of string * 2.. so it is possible that a variable length string *does* have a header of 20 bytes, like Dave said.. Though I wouldn't know how to confirm it. [Edit] God.. I don't have the time to go through and point out all the flaws in this.. My suggestion.. Don't take any of this on faith. Test it for yourself.. For instance.. Len is not LenB / 2.. Try Code: Dim Blah As Long
Debug.Print Len(Blah) Debug.Print LenB(Blah) Also.. I could be wrong, but I believe that images are all loaded into memory as bitmaps.. The compression (JPG, GIF, PNG) is just for smaller storage and faster loading time. You can actually test this by opening up the same size images stored in 2 different formats with paint. (I tried it with a completely white background in both BMP and PNG formats..) |
Author: | Xlithan [ Thu Jan 18, 2007 5:19 pm ] |
Post subject: | |
Does CodeFixer fix a lot of the mentioned problems? I've noticed it comments out all unused sub routines, variables, and adds the $ sign to those strings, as well as replace "" with vbNullString. But how helpful is it over-all? |
Author: | Spodi [ Thu Jan 18, 2007 11:16 pm ] |
Post subject: | |
Lets put it this way, you'll probably never notice the speed difference. But for an engine, you want to give as powerful as a base as possible, so every little bit counts. |
Author: | Xlithan [ Fri Jan 19, 2007 3:30 am ] |
Post subject: | |
yep, all optimizations eventually add up to a noticable change, every little counts, as they say. |
Page 1 of 1 | All times are UTC |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |