The answer depends on how your listboxes are being populated.
Because you said they are dynamic, you can probably get what you want with the listcount property, example:
MsgBox ListBox1.ListCount
If your listboxes are being populated with their RowSource property, ListCount will give you a potentially false number, as it will represent the count of cells in the range, which can be higher than the actual items in the listbox if some cells in the rowsource range are empty. In this case you can loop through the items with a counter, but since you asked for the most efficient method, the loop option can be examined only after you say that you are using rowsource, which I am guessing you are not doing, given your eference to the dynamic nature of the userform.