leshay

Hi

How would I go about getting the code between the lines out of the inner loop to help speed up the section

For x = 0 To i.Items.Count - 1
Dim t As New Label
t.AutoEllipsis = True
t.Text = i.Items(x)
t.Font = New Font("Arial", fsize, FontStyle.Regular, GraphicsUnit.Point)
t.Location = New Point(8, yyoffset + 4)
t.BackColor = Color.AliceBlue
t.BorderStyle = BorderStyle.Fixed3D
t.Width = len
t.Height = Label6.Height + 1
Me.Controls.Add(t)
Dim s As String = Conf.CNumb(Configure.CName.IndexOf(i.Items(x)))
getprog(s)
Dim cc As Integer
For cc = 0 To progC - 1
Dim gg As New Label
'--------------------------------------
gg.Font = New Font("Arial", fsize, FontStyle.Regular, GraphicsUnit.Point)
gg.Height = Label6.Height + 1
gg.AutoEllipsis = True
gg.BorderStyle = BorderStyle.Fixed3D
gg.BackColor = Gcol
'--------------------------------------
gg.Location = New Point(xxoffset * GridScale, yyoffset - 7)
gg.Width = pp(cc)(22) * GridScale
gg.Text = pp(cc)(0)
AddHandler gg.Click, AddressOf epg_Click ' all grid click
Pa.Controls.Add(gg)
pc += 1
xxoffset += pp(cc)(22)
Next
progC = 0
yyoffset += Label6.Height + 4
xxoffset = 0
Next




Re: Visual Basic Express Edition Trying to speed up a block of code

Dave299

I don't think you will be able to speed it up like that. All the lines you have highlighted are used to configure the labels so they have to run for each label whether they are within the loop or not.

You could create a new class for the label and put some of the code in its constructor which would look neater but I doubt if it would have any impact on the speed which will be determined mainly by the time taken to draw all the controls. If you are using a background image for the form you may also find that is having a large impact on the draw time.

As you seem to be creating some sort of a grid to click on have you considered just using a single control on which the grid can be drawn using graphics methods. When you click on it the X and Y mouse co-ordinates would then allow you to work out which element has been clicked.





Re: Visual Basic Express Edition Trying to speed up a block of code

leshay

Hi
Thanks for your reply Dave. I see what you mean, but I doubt I could deal with the data in the way you suggest.

The grid I am using has up to 5000 labels, each of 'time' dependant length and font dependant height. I can see that your suggestion is possible, but my coding wouldn't be up to it.

I had thought that a label with the properties I wanted to take out of the loop could be set up and just 'copied' and then adjusted for the properties I need to calculate would have given some speed advantage - however, my attempts to do that didn't work - and from what you say, couldn't work.

But thanks anyway.





Re: Visual Basic Express Edition Trying to speed up a block of code

ssta

You could try using With...End With
You could also try creating a control array and using Controls.AddRange instead

I haven't tried any of these sugestions so let me know how it works.






Re: Visual Basic Express Edition Trying to speed up a block of code

Dave299

Using an array and AddRange will make the problem many times worse.

Really 5,000 labels on a form is just not a realistic design. It's not the creation of the label objects that is the problem - that actually takes very little time as you can see if you take out the line that adds them to the form's controls collection and then time how long the loop takes to run.

Adding them to the form's controls collection takes a certain length of time and that time is not a linear progression. As more controls are added it takes longer and longer to add another one.

Then actually displaying them on the form takes a relatively long time.

Displaying this information with graphics methods should be relatively straightforward but if I understand you correctly the labels are all different sizes so the difficulty would be in determining on which area you clicked.

<Edit>

Actually having given it further thought it wouldn't be that difficult as all the areas are rectangles so all you have to do is determine which rectangle contains the point on which you clicked.

</Edit>




Re: Visual Basic Express Edition Trying to speed up a block of code

ssta

Dave I think you're absolutely right about the design being unrealistic. I didn't notice at first glance that 5000 labels were involved. Just for fun though I'd tried my previous suggestions to see what would happen. The results weren't stunning.


The With block idea; sucked. Unlike VB6 the With block had no effect-- Which kind of makes sense since the VB.NET compiler can optimize this kind of thing. So much for that bad idea.


The AddRange method on the other hand gave a whopping 10% performance increase. Yeah! Not. 10% in this case is like walking to the Moon in 10% less time.


Now back to the problem at hand.


Using graphics methods is defiantly the way to go. I not quite sure what the paint method might look like because I don't have enough information. The hit-test would look something like this:


Private Function GetCellFromPoint(ByVal location As Point) As Point

Dim p As New Point()

p.X = ((location.X - (CELLWIDTH/ 2)) / (COLUMNS * CELLWIDTH)) * COLUMNS

p.Y = ((location.Y - (CELLHEIGHT / 2) - OFFSETTOP) / (ROWS * CELLHEIGHT)) * ROWS

Return p

End Function





Re: Visual Basic Express Edition Trying to speed up a block of code

leshay

Thanks for input.

I do realise that the design for this program is somewhat lacking. It is no surprise to me to hear that considering that there was no planning at all for this project. I merely started with a blank page and have managed to produce a working program (well working in as much as it does what I want), but that grid takes about 30 seconds to display with about 20 rows (would take longer with more rows obviously).

I have not, as yet, even looked at the graphics side of things. I can see that I will probably have to.

Yes, the grid is made up of a lot of labels, each of the same height but a width determined by time (a TV EPG grid).

I can actually live with the time taken for my current selection of rows, but, if I was ever to let others try it, they may have a need for a lot more rows than I do and so would have a much higher time overhead - this was what prompted the original post.

Looking at the block of code for the hit test indicates that I woud need to test against stored cell sizes Also, mention of columns brings in the fact that there are no columns in the grid since it is a jagged grid. I would presumable need to store details for each and every cell rather than a x by y grid shape.

Anyway, at some stage, I must have a closer look at some of the points you guys have raised - and thank you for that.






Re: Visual Basic Express Edition Trying to speed up a block of code

Dave299

Rather than use an array of labels define an array of rectangles. These are easy to draw or fill using graphics methods. You can also define a string format to determine how text would be displayed within the rectangles.

To determine which rectangle you click on simply use the Rectangle.Contains method on each element to determine if the point at which you have clicked is contained within

The following example probably contains most of what you will need.

Code Snippet

Public Class Form1

Dim Rects(80) As Rectangle

Dim Fmt As New StringFormat

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Me.Size = New Size(480, 510)

Fmt.Alignment = StringAlignment.Center

Fmt.LineAlignment = StringAlignment.Center

For count As Integer = 0 To 80

Rects(count) = New Rectangle

With Rects(count)

.Size = New Size(50, 50)

.X = 10 + (count Mod 9) * 50

.Y = 10 + (count \ 9) * 50

End With

Next

End Sub

Private Sub Form1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick

For count As Integer = 0 To 80

If Rects(count).Contains(e.Location) Then

Dim G As Graphics = Me.CreateGraphics

G.DrawString(count.ToString, New Font("Arial", 18, FontStyle.Bold), Brushes.Black, Rects(count), Fmt)

G.Dispose()

Exit For

End If

Next

End Sub

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

For count As Integer = 0 To 80

If count Mod 2 = 0 Then

e.Graphics.FillRectangle(Brushes.Yellow, Rects(count))

Else

e.Graphics.FillRectangle(Brushes.Blue, Rects(count))

End If

Next

End Sub

End Class





Re: Visual Basic Express Edition Trying to speed up a block of code

leshay

Thanks for that Dave. I will have a go with that snippet and see what happens.




Re: Visual Basic Express Edition Trying to speed up a block of code

ssta

If your grid is like an EPG that you refered to than it in fact has a fixed number of columns. A guide for example that displayed 6 hours at a time in .5 hour incrments would have 12 columns. How the columns (or slots) your data occupies can vary.

Dave's code outlines what you will have to do in the paint event to draw your grid. I point out that because some of the drawing happens outside of the paint event it will be lost whenever a paint event occurs.

The scanning (for loop) tequnique for painting is the only way to go. You should consider creating a class to define each entry in.

The class might look something like this:

Public Class Slot

Public StartTime As DateTime 'Divide to get starting column position

Public EndTime As DateTime 'Divide to get starting column position

Public Text As String

Public Selected As Boolean

End Class


To instaniate the class:

Private _Slots As List(Of Slot) = New List(Of Slot)










Re: Visual Basic Express Edition Trying to speed up a block of code

leshay

Hi ssta

Thanks for your reply.

I don't quite agree with you in as much as my grid doesn't have columns as such. Each label I am using in my grid at the moment has it's width determined by the duration of the programme - and so, is a jagged grid versus a regular grid that you describe.

Now, I am not suggesting your idea is not valid, just that it differs from the concept of my project. You can certainly have (say) a 6 hour panel of 1/2 hour slots, but then how to slot in a 45 min programme as 1 'entity'

If I manage to pursue the graphics approach, I would have to start from scratch again - not at all something I am against doing, but at some time other than right now. I do have a working project with this at the moment, and I will try to finalize it (not that any of my projects are ever finalized Smile

At the moment, my grid takes about 45 - 60 seconds to fill - this is something I will have to live with (at the moment) or until I have a look at re-doing the project with all the ideas proposed in this thread.