Tips_todo   >   Misc   >   Speedingup Studio

Speedingup Studio

If you are converting an existing Omnis Classic application to Omnis Studio, both you and your users are in for a surprise. Your application will likely run slower in Studio than it did in Classic.

Studio gives you lots of neat new objects and features and it gives you an object-oriented development tool, but there is a price to pay. Don't try running Studio on old hardware it's too slow.

This section provide information on things you can do in Omnis Studio to help your application run quicker.

If you know of additional things or have additional information please email me.

COMMENTS BY REG PALING (a snip from the List Server)

Occasionally in the past we've had a lister getting into a panic about performance of their new Studio app because they made a few design decisions which didn't work well on the first attempt, and with help from the list they've made a few adjustments and it has all been sweet.

So, with Studio you do have to design carefully to avoid creating structures that get bogged down in too many levels of processing. If you really need to create complexity, then don't be shy about demanding the fastest possible hardware to run it on. It's your choice as a designer: create simple structures and they will run fine on six-year-old hardware, or create complex structures which require a newer-generation machine.

For those who have simple applications, the conversion from O7 to Studio can be fairly easy. For those with complex applications in O7, think about how much time and effort you applied to fine-tuning your application, but then don't expect that same fine-tuning is going to work well in Studio - maybe the opposite, and you'll have to put in double effort to dismantle all that work and then re-do it.

All in all, it's worth the move, and we just need to unlearn some habits and learn a few new ones. Cheers, Reg.

Complex Grids

There have been many complaints about the "wave effect" redraw of complex grids. You can do almost anything with a complex grid, but as the name states, they are complex. Each line of a complex grid is in effect a separate instance. A 100 line complex grid has 100 line "instances". Each instance can have exceptions for each field inside of it.

I use complex grids whenever I want the user to be able to edit data directly in a list. (Purchase Order items, AR and AP Invoice items, etc.) Fortunately, the complex grids in my application are generally under 10-40 lines so I haven't hit the "slow redraw wave effect" that others complain about.

If you are using 100+ line complex grids with lots of exceptions and $event methods you will likely get frustrated with complex grids. If you hit the slow complex grid redraw problem with your application, send an email to Tech Support to let them know you are not happy with the situation. (Hopefully engineering will find a solution if enough developers keep complaining.)

IDE Tools

Some users have reported faster startup and speed improvements by loading less of the IDE tools.

You can do this through the Tools menu > Preferences > General tab > idetools property.

Clicking on this property gives you a checkbox list where you can uncheck tools you don't need. I uncheck vcs.lbs (version control system).

I'm not certain what a number of the other tools are for. You can experiment and see if it helps.

Max Cached Classes

Under the Tools menu > Preferences , there is a property $maxcachedclasses. I believe Omnis defaults it to 100. Bump it up higher. Some developers set it as high as 1000.

Before Omnis added this property my application would run slower and slower the longer I used it until finally I'd have to quit and restart Studio. If you find your application running slower the more windows you open and then longer you run it ... there's a good chance you need to bump $maxcachedclasses up. To set this for runtime users I set it using notation in the main library's Startup_Task.

There is no clear answer on the best setting for this property. The default is 100. At the time of writing this tip I have set to 200 in the Startup_Task of my main library to make sure runtime users of my application are automatically set to 200.

Do $prefs.$maxcachedclasses.$assign(200)

Setting $maxcachedclasses to some wildly high number is not advisable as it could start to hamper performance.

ADVICE FROM TECH SUPPORT

Some developers have noticed that issuing $definefromsqlclass causes a sizeable performance hit.

The following is advice from Tech Support on this issue:

At present I am unable to fully explain exactly what is happening here. Our thought is that this may be connected to class caching. In that the sqlclasses are not in the cache and must be read from disk. This may mean that you need to adjust $root.$prefs.$maxcachedclasses to remove this problem. We have not seen the problem and therefore this may not be the case.

I include the details on the sys functions that may be used to analyse the caching performance.

sys(190) returns the number of times Omnis has loaded a class from disk and added it to the memory class cache.

sys(191) returns the number of times Omnis deleted a memory class cache entry, when it added a
class to the cache, meaning that the class deleted from the cache may need to be reloaded.

sys(190) and sys(191) provide information you can use to monitor the impact of changing the preference $root.$prefs.$maxcachedclasses. Too low a value for this preference may result in a performance hit, due to too many classes being repeatedly loaded from disk.

OmnisSQL

If you are using OMNISSQL note that it is not a "commercial backend" SQL server. It's a great SQL learning tool, it's free, and it works amazingly good (I'm still using it for 10 users and 300MB data file), but don't expect it to work like Oracle or DB2. OMNISSQL will bog down if you include too many arguments in you SQL select, include an ORDER BY, or try join too many tables (more than 4 or 5)

INDEXES

Be sure to use CASE SENSITIVE indexes for all non-numeric data. If you don't Omnis goes through every record making the index useless.

Consider date fields to be non-numeric. Use indexed fields for your selects and joins on tables with large numbers of records.

JOINING TABLES

Be sure to put the "main table column" to the right side of your table joins.

If you were running a report on the books written by Shakespeare in a library joining the "book" table and the "author" table, we could write the join statement two ways:

1. WHERE book.author_key = author.author_key AND author.Name = 'Shakespeare'
2. WHERE author.author_key = book.author_key AND author.Name = 'Shakespeare'

The first way has the main table on the left causing OmnisSQL to go through every record in the database, the second way has the main table on the right and runs lightning quick.

COMPLEX SELECTS

I find it quicker to grab more data than I need, then use $search followed by $remove(kListKeepSelected) or $remove(kListDeleteSelected). Do your sorting after the fetch using $sort.

You will need to experiment with you select statements. I tell my users if any report is taking longer than a minute or two, let me know. For most reports I can usually figure out a solution and get it down to a minute or less.

CONSIDER MOVING TO A REAL SQL BACK END.

If your client needs more speed, they can probably afford to invest in an industrial backend. At the time of writing the beta release of FrontBase is out. I understand it should run around US$500 for unlimited users and give equal support to Mac and Wintel clients. That's a pretty inexpensive solution that will make your OMNISSQL select and fetches look like they are standing still.

That's the beauty of SQL vs. DML ... easy hookup to 3rd party backend SQL.

Subwindows

If you load up a window with 100+ fields using tab panes and/or page panes opening the window will seem to take forever. The reason is that the Studio window supports multiple instances, superclass/subclass structure, $construct for every field in the window, etc. etc. All that neat OO stuff comes at a price.

The solution I use it to use tab panes and page panes. Each layer of the tab/page pane has an empty subwindow field set to kEFposClient and the $classname left blank. Open a window like this is very fast. :-)

Using notation $assign the $classname for the tab/page panes only as the user requests to do so. So in reality tab/page pane 1 will have its $classname set when you open the window. When the user clicks on a different tab you intercept the click and set the $classname. (See sample code below)

Keep your windows light and 'flat'. Using subwindows also allows you to reuse the same window in many places. I have a single superclass window with a 5 layer page pane and 1 of the layers has a 5 layer tab pane. Each layer has an empty subwindow set to kEFposClient. This same superclass window is instantiated for virtually every window in my application. I have a single subwindow with a headed list. This single headed list subwindow is instantiated for virtually every headed list in my application ... it's properties are assigned notationally on the fly.