Ваш тестовый пример далек от основания. Когда вы выполняете фактическую вычислительную работу в методе threadWork, вы обнаружите, что результаты сильно отличаются. TPL использует пул потоков внутри, так что это вопрос Threadpool против потоков. Причина, по которой TPL настолько отличается по сравнению с потоком потоков, вероятно, связана с природой самого пула потоков (вернемся к этому позже).
Посмотрите, сколько времени потребовалось на завершение темы. Ваш метод тестирования только спит в течение 5 секунд, вот и все. Куда делась другая .43 секунда? Правильно, к созданию и уничтожению самого потока и связанных с ним издержек, включая переключение контекста. Пул потоков имеет очередь потоков, которые можно использовать для одновременного выполнения. Все зависит от Threadpool и его конфигурации, позволяющей создавать и уничтожать дополнительные потоки в любое время. Когда вы запланируете 60 элементов в Пуле потоков, скорее всего, Пул потоков не создаст 60 потоков, чтобы обрабатывать все элементы одновременно, а вместо этого использовать часть этого количества и обрабатывать несколько элементов на поток. Поскольку ваш метод тестирования только спит, это объясняет большую разницу между временем, потраченным на потоки, и временем, потраченным на пул потоков.
Поскольку TPL использует Threadpool внутренне, и до того, как вы запустите тест ThreadPool, логично предположить, что на этом этапе: в Threadpool было доступно меньше потоков, но из-за запуска TPL было создано больше потоков для Threadpool, поэтому, в свою очередь, при выполнении теста Threadpool изначально было доступно больше потоков, что объясняет разницу между TPL и Threadpool.
Практически, вы хотите максимально использовать Threadpool, особенно для вычислительных операций. Когда вам нужно синхронизироваться с внешним ресурсом, таким как загрузка чего-либо из Интернета, я рекомендую не использовать поток, а один из более сложных асинхронных вариантов, доступных в .NET для получения этого конкретного ресурса.