This is actually a good question.
In the core there are some blocks that use _beforeToHtml to prepare the data. See for example Mage_Catalog_Block_Product_List, Mage_Catalog_Block_Product_List_Crosssell and a lot of admin blocks.
There are also blocks that use the __construct method to process some data. See Mage_Catalog_Block_Product_View_Options, Mage_Checkout_Block_Cart and again a lot of admin blocks.
Some of them use _toHtml to process data. See Mage_Rss_Block_Catalog_New, Mage_Sales_Block_Order_Email_Items_Order_Grouped.
My vote goes for... neither.
I like using lazy loading. So in my custom blocks I implement methods that process data only when needed. Let's take your example. "The block needs a collection."
I create the method
public function getSomeCollection(){
if (!$this->hasData('_some_collection')){
$someCollection = 'Magic happens here';
$this->setData('_some_collection', $someCollection);
}
return $this->getData('_some_collection')
}
This way I'm sure that my collection is loaded only when calling it the first time. The result is cached in the block _data member so it's not processed twice if called twice.
So I call this method in the phtml file when needed.
The _ in the front of _some_collection is there so I'm sure that you cannot call setSomeCollection. If you don't need this restriction you can skip the underscore.