One thing that makes the difference between a canonical labeled page and a 301 redirect is the initial HTML code you see.
Say you have these two URLs:
...and you use a 301 redirect from the first URL to the second.
If you analyze the results in something other than an ordinary web browser, you should see a page that tells you the page has moved with the word "here" as a hyperlink to the new page, or something similar.
I use the command-line tool CURL to test some pages, and on the redirect pages, the following HTML is shown:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<title>301 Moved Permanently</title>
<p>The document has moved <a href="http://example.com/newurl">here</a>.</p>
Also, I ran
CURL -I to see the headers of the redirect, and the output is:
HTTP/1.1 301 Moved Permanently
Date: Sat, 30 May 2015 17:47:32 GMT
Content-Type: text/html; charset=iso-8859-1
As for the pages labeled as canonical, you will never see the moved status code or the moved page message like above.
Each way has its pros and cons.
If you use canonical, the advantage is that there may be fewer requests to the server because two pages are duplicate and theres little chance one will look at the other duplicate page especially if its not advertised in any sitemap submitted to any search engine.
The disadvantage is that
rel=canonical might be something some search engines still do not understand and therefore, your ranking could be affected for those search engines. Also, if the contents of the affected pages change to the point where two pages are no longer duplicate or related, then using
rel=canonical might work against you depending on how google perceives it.
The way I prefer to do it is via the 301 redirect.
The advantage with 301 is that users get moved to the correct page and the URL in the clients web browser is updated to display the new URL instead of the old one. Also, all search engines in the world will be happy with this method since 301 redirects are not something new like rel=canonical is.
The drawback is that an extra request is required to complete the redirect and in normal web browsers, the request is often automatic because most people don't like seeing messages like "the document has moved here".
Having weighed everything, I personally would continue with 301 redirects and optimize my server to make the latency to a minimum. On a well optimized server, serving the first byte of a page locally with a 301 redirect served should take no more about 400 milliseconds.