Friday, 12 August 2016

Scanning is slow - should I split?

Almost 4 years ago, I wrote a post entitled Scanning is slow.  Well, to be fair, it is.

The example code that I gave was for counting how many times a substring appeared within a string...

  temp = list
  total = 0
  scan temp,"ABC"
  while $result > 0 )
    total = total+1
    temp = temp[$result+3]
    scan temp,"ABC"
  endwhile

I gave a perfectly simply alternative which performed much better in this scenario, using $replace and $itemcount

However, I found myself in a similar situation yesterday, but I couldn't use this trick, because I needed to loop through, searching for certain substrings, but without changing the string that I was looping through.

A thought occurred to me, which was that I was always taking the string from after the value I'd found and scanning again, so in this case, what about using $split instead?

To compare against to above, I came up with something like this...

  temp = list
  total = 0
  $result = $split(temp,1,"ABC",lhs,rhs)
  while ( $result > 0 )
    total = total+1
    temp = rhs
    $result = $split(temp,1,"ABC",lhs,rhs)
  endwhile

I tested this by doing 500 iterations, on a string with 500 instances (so total was 250000 at the end)...

$scan: 20.94, 20.67, 20.85 - almost 21 seconds.
$split: 27.09, 27.48, 26.83 - around 27 seconds.

So $split definitely looked worse off, it looked like $scan was better suited to what I needed (as I wasn't interested in the left hand side).

However, these tests have been seeing whether I can use $split to improve my $scan loop, and this seemed a little unfair now I'd proven it couldn't, so I thought I'd flip it on it's head and see if $scan is better at doing what $split is designed for.


So for $split this is quite easy, a simple line which splits the string into two parts...

  $result $split(temp,1,"~",lhs,rhs)

Using $scan this is a little more complicated, and requires a little string manipulation...

  $result $scan(temp,"~")
  lhs = temp[1:$result-1]
  rhs = temp[$result+1]


When I compared the two over 2,000,000 iterations, I got these results...

$split: 10.19, 9.78, 10.01 - around 10 seconds.
$scan: 16.60, 16.51, 16.82 - over 16 seconds.

So I've worked out that $split is good for splitting and $scan is good for scanning... Why am I writing this up in a blog post, you might wonder!

Well I then considered the fact that I was splitting a string on a delimiter that I knew existed.  And in the real world situation I was working on, this wasn't a fair assumption, as often the delimiter would not be there.  So I tried this again, but with a different delimiter, that wouldn't be found in the string...

$split: 10.66, 10.73, 10.87 - a little over 10 seconds.
$scan: 9.20, 9.00, 8.44 - around 9 seconds.

So it looks like it's not quite as straightforward as I thought.  However, the saving when it is found is quite a lot larger than the loss when it's not found, so maybe $split is still best overall.

Summary: If you're looking to scan through a string, use $scan, and if you're looking to split a string (especially if you expect the delimiter to be there), use $split.

Friday, 8 July 2016

Training videos for Uniface developers

Yesterday there was a blog post by Ton Blankers on Uniface.info covering HTML5, Javascript and CSS3 Training Videos for Uniface Developers.  

This post highlights a special series of training videos on web topics for Uniface developers. They are available on Uniface.info, and include both introductory and more advanced videos.

They're well worth checking out, as they cover things like Canvas, Geolocation, LocalStorage, JSON and more.

Summary: Check out the full blog post here for more details and links to the videos.

Friday, 17 June 2016

Putlistitems - successive occurrences

I've used putlistitems a lot, it's very useful.  Different switches all it to do different things, so for example, /occ will populate a variable with an associative list of field names and values, something like this...

  putlistitems/occ varMyList,"ENT"

"varMyList" will now be something like "FIELD1=VALUE1·;FIELD2=VALUE2·;etc".

This can further be modified by adding /modonly, which will only add field values to the list which have been modified since the record was retrieved, something like this...

  putlistitems/occ/modonly varMyList,"ENT"

However, the one I tend to use most is /id.  This will take the values of the specified field from multiple occurrences and put them into a list, something like this...

  varMyList = "FIELD1"
  putlistitems/id varMyList

"varMyList" will now be something like "VALUE1·;VALUE1·;etc", repeated for each occurrence.

This allows you to quickly grab the values of the field(s) you're interested in, without having to loop through the occurrences in order to build the list, which is much better for performance.

Or you can also use it to update the representations in a list, for example, backing up a load of field or register values...

  varMyList = "$1·;$2·;$3"
  putlistitems/id varMyList

"varMyList" will now be something like "$1=REG1·;$2=REG2·;$3=REG3".

All of this is well documented in the Uniface manuals, so you may well be asking me why I'm telling you this.  Fair question.

I never realised that the first use of /id, taking the values of the specified field from multiple occurrences, was actually successive occurrence.  This means that it will start on the current occurrence and loop through to the end, completing the hitlist if required.

The manuals make this clear, with the following note...
To ensure that the entire set of occurrences in the component is being addressed, make the first occurrence the current occurrence.

What this means is, use setocc first, like this..

  setocc "ENT",1
  varMyList = "FIELD1"
  putlistitems/id varMyList

I hope I've not been caught out by this in the past!

Summary: putlistitems/id will look at successive occurrences, so if you want the whole hitlist, remember to make sure the current occurrence is the first occurrence.

Wednesday, 24 February 2016

Uniface Lectures - Deployment

The first "Uniface Lecture" on Modernisation was really interesting, although it did cover a lot of the same ground as the series of blog posts on Modernisation, which I've also posted about before (herehere and here).  It went well though, and I expect the rest in the series to be just as good, if not better!

I did get caught out by the setup required (which we were told about in advance, so it's my own fault), so if you don't already have a browser plugin for "Skype for Business" then you should get that sorted out in advance by following this article.


The next webinar in the series is going to be on Thursday 10th March, 8am and 4pm (CET). 

Deployment
  • Standard deployment (with UAR's) versus classic deployment (with URR's and DOL's) 
  • The benefits of standard deployment 
  • Things to consider when deploying your Uniface application using the 64bit version of Uniface.
Although I'm aware of standard deployment, I've only ever used classic deployment, so I'm interested to find out more about the differences and what I might be missing out on.


As I said in my last post, I'm just passing this information on because I think they'll be useful.  If you want more information, or to hear it from the horses mouth, check out the website...


Tuesday, 9 February 2016

Uniface Lectures

Uniface have got a new series of "lectures", or webinars, coming up soon.  These sound like a great idea, and are covering a range of different subjects.

 Uniface Lectures


The webinars are one a month, and topics published so far are...


Modernization - Thursday 18th February (8am or 4pm CET)

How to give your Uniface applications a Windows 10 look and feel, and how to work with different screen resolutions.  



Deployment - Thursday 10th March (TBC)

How to more easily distribute and update your Uniface applications.


JavaScript - Thursday 14th April (TBC)

How to use Uniface in existing web pages.


Mobile - Thursday 12th May (TBC)

How to build your first Uniface mobile app.


Integration - Thursday 16th June (TBC)

How to integrate your Uniface applications with Dropbox and OneDrive. How to use semantic URLs for Uniface RESTful services.


I'm just passing this information on because I think they'll be useful.  If you want more information, or to hear it from the horses mouth, check out the website...



Wednesday, 23 December 2015

Drag and drop

Yesterday I read an interesting article about drag and drop in Uniface, aptly named Drop It Like It's Hot.  

It actually goes into plenty of detail about how to add drop areas into your own Uniface forms, which is something I'd definitely like to try some time.  But what really interested me was the opening paragraph...

What very little people know is that in the Import Repository Objects component there is a small section where you can drag your export files from Windows Explorer. After you drop them, the File name box is updated with the list of files that you dropped. The red section is where the drag-and-drop field is located.


I tried this today and it definitely works.  You learn something new every day!

Summary: You can drag and drop export files onto the Import Repository Objects popup, which is really quick and convenient.

Tuesday, 10 November 2015

Modernising Uniface - part 3

Over the past couple of weeks I have posted about Modernising Uniface (and here), and this is the third and final post in this series.

The third post from Theo Neeskens was primarily concerning the new flat buttons, which look like this...



As you can see, the new flat blue buttons, on a white background, are on top of the old grey/grey.

The first thing they needed to do was categorise the different painted button types, and they came up with five...
  1. IDFButtonBottom - for the big buttons at the bottom of dialogs
  2. IDFButtonSide - for the big buttons at the right-hand side of dialogs
  3. IDFButtonSpecial - for the other buttons
  4. IDFButtonImage - for the small buttons without labels (eg. ">>")
  5. IDFButtonHeader - for the buttons which make up the header on simulated grids

So then there are a few jobs that needed to be done...
  • Change the properties in the configuration file for these widget types
  • Match modelled widgets with painted widgets
  • Set the properties on the painted buttons
  • Set the properties on the modelled buttons



Again, many of the these jobs were achieved with tools, and all of these have been provided in a zip file, to be downloaded and modified if you wish, but not supported by Uniface and used at your own risk.

The full blog post is definitely worth checking out, including the "Wishes" section at the end... Modernizing Uniface 9.7: The buttons


Summary: Uniface has successfully (in my opinion!) modernised it's IDE in version 9.7, meaning we don't have to wait for Uniface 10.