views_embed_view is just a wrapper for views_get_view: function views_embed_view($name, $display_id = 'default') { $args = func_get_args(); array_shift($args); // remove $name if (count($args)) { array_shift($args); // remove $display_id } $view = views_get_view($name); if (!$view || !$view->access($display_id)) { return; } return $view->preview($display_id, $args); } So how would you set dynamic arguments on views_embed_view? With views_get_view you can at least do this: $view = views_get_view($view_name); if (!$view || !$view->access($display_id)) { return; } $view->set_display($display_id); $view->set_arguments($variables); $view->pre_execute(); $view->execute(); return $view->render(); module_invoke for block is too roundabout and limited for my liking. Why limit yourself to a block when you can choose from any display available? views_block_view contains this snippet: if ($view = views_get_view($name)) { So it also uses Views_get_view. Performance-wise I reckon the differences are negligible. So, IMO, views_get_view wins.