Very true. From tests on several hundred thousand rows, the cell formulas themselves only appear to take around a microsecond to calculate and that still doesn’t change much with INDEX/MATCH v double LOOKUP specifications. These results tend to agree with Jeff’s initial take that you’re losing out from splitting calculations into separate cells with well optimised functions like these but you won’t really notice unless you have such large lookup tables to fill.

One other point is that when there are multiple values equal to the lookup value, the lookup formula seems to go through the list in a linear (not binary) fashion. So if column A consists entirely of 1’s, filling down =LOOKUP(1,A:A) takes a lot longer than =LOOKUP(2,A:A).

]]>Using a modified version of the joeu200 routine, with the lookup functions in 50 rows, my match/index function really speeds up, and is 50-80% faster than the binary VLookup with check.

My procedure was much the same as yours, except I initially selected my lookup values so that they all had matches, and then I modified half of them so there was no match.

The ratio for (Match-Index)/(Exact VLookup) was about 6800 when all the lookup values had an exact match, and 10700 when half of the values did not have any match. That makes sense, because if there is no match the exact VLookup has to check the entire list.

My UDF times were of the same order of magnitude per lookup as the subroutine took for 50 lookups, so it looks like most of the time for the UDF was data transfer.

]]>My code is based on the routine from joeu2004 at http://www.mrexcel.com/forum/excel-questions/762910-speed-performance-measure-visual-basic-applications-function.html

This thread is worth a read, because it makes this important point: we cannot measure the performance of “a” formula simply by measuring one instance of the formula. (But that does depend on the nature of the formula and the situation that we are trying to measure. Sometimes we need to measure one instance of a formula, but increase the size of ranges that it references in order to overcome the effects of overhead.)

I’ll post my TimeFormula routine in the near future…I’m just making some additional tweaks.

]]>Function LookTime(datrange As Range, lookval As Double, matchcol As Range)

Dim STime As Double, ResA(1 To 1, 1 To 4) As Variant, Rtn As Double, i As Long, Indx As Long

STime = Timer

For i = 1 To 100

Rtn = WorksheetFunction.VLookup(lookval, datrange, 1, False)

Next i

ResA(1, 1) = Timer - STime

STime = Timer

For i = 1 To 100000

Rtn = WorksheetFunction.VLookup(lookval, datrange, 1, True)

Next i

ResA(1, 2) = Timer - STime

STime = Timer

For i = 1 To 100000

If (WorksheetFunction.VLookup(lookval, datrange, 1, True)) = lookval Then Rtn = WorksheetFunction.VLookup(lookval, datrange, 2, True) Else Rtn = 0

Next i

ResA(1, 3) = Timer - STime

STime = Timer

For i = 1 To 100000

Indx = WorksheetFunction.Match(lookval, matchcol, 1)

If (WorksheetFunction.Index(matchcol, Indx, 1)) = lookval Then Rtn = WorksheetFunction.Index(datrange, Indx, 2) Else Rtn = 0

Next i

ResA(1, 4) = Timer - STime

LookTime = ResA

End Function

Dim STime As Double, ResA(1 To 1, 1 To 4) As Variant, Rtn As Double, i As Long, Indx As Long

STime = Timer

For i = 1 To 100

Rtn = WorksheetFunction.VLookup(lookval, datrange, 1, False)

Next i

ResA(1, 1) = Timer - STime

STime = Timer

For i = 1 To 100000

Rtn = WorksheetFunction.VLookup(lookval, datrange, 1, True)

Next i

ResA(1, 2) = Timer - STime

STime = Timer

For i = 1 To 100000

If (WorksheetFunction.VLookup(lookval, datrange, 1, True)) = lookval Then Rtn = WorksheetFunction.VLookup(lookval, datrange, 2, True) Else Rtn = 0

Next i

ResA(1, 3) = Timer - STime

STime = Timer

For i = 1 To 100000

Indx = WorksheetFunction.Match(lookval, matchcol, 1)

If (WorksheetFunction.Index(matchcol, Indx, 1)) = lookval Then Rtn = WorksheetFunction.Index(datrange, Indx, 2) Else Rtn = 0

Next i

ResA(1, 4) = Timer - STime

LookTime = ResA

End Function

The results on a table with 1 million rows, with the lookup value about 3/4 of the way down were:

Exact / Binary x 1 / Binary x 2 / Match + Index x 2

0.797 0.203125 0.390625 0.8125

Note that the first result is for only 100 loops, compared with 100,000 for the others.

So I found that the binary VLookup with check was about 2000 times faster than the Exact VLookup, but also about twice as fast as the Match + Index!

I’m not sure why my Match + Index results were so much slower than Jeff’s. Maybe because it’s all in VBA and so doesn’t use multi-core processing.

Anyway, I’m going to turn this into a UDF to return the answer, rather than the time (using the double VLookup), to save myself some typing, and also so I can add an optional tolerance, rather than checking for an exact match.

]]>0.00114776 seconds (VLOOKUP)

0.00111296 seconds (MATCH)

In short, it certainly ain’t worth the hassle of setting up another column.

]]>Sub M_snb()

DoCmd.TransferText acExportHTML, , "BlendedRackReport", "G:\blended.html"

- - - - - - -

htmlbody=application.createobject("scripting.filesystemobject").opentextfile("G:\blended.html").readall

- - - - - - - -

End Sub

DoCmd.TransferText acExportHTML, , "BlendedRackReport", "G:\blended.html"

- - - - - - -

htmlbody=application.createobject("scripting.filesystemobject").opentextfile("G:\blended.html").readall

- - - - - - - -

End Sub

I’d like to share what I’ve done recently.

I am just redoing my website from scratch (WordPress) and couldn’t adept to WordPress online editor. I like to use the best text editor in the world to write, that is, Word for Windows. So I tought “maybe if I export in HTML, I can just copy and paste the HTML in the source of WordPress”. Hahahah. The HTML has tons of overhead, and just a document with a small paragraph generates hundreds of HTML lines, and it is totally incompatible with WordPress.

So, whenever I want to write a new blog post, I do everything in Word, run the macro to genereate the WordPress-compatible HTML and just paste it there.