Dlaczego ten równoległy algorytm działa wolniej niż jego sekwencyjny odpowiednik?

Sekwencyjny:

void do(List<D> d, final List<C> c) {
for (D datum : d)
    getChampoid(datum, c).tally(datum);

Równolegle:

static final int procs = Runtime.getRuntime().availableProcessors();
static final ExecutorService pool = Executors.newFixedThreadPool(procs);
void do(List<D> d, final List<C> c) {
    List<Future> futures = new ArrayList<>();
    for (final D datum : d)
        futures.add(pool.submit(new Runnable() {

            @Override
            public void run() {
                getChampoid(datum, c).tally(datum);
            }

        }));
    for (Future f : futures)
        try {
            f.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

Jestem zakłopotany, ponieważ dla mnie wyglądają tak, jakby robili dokładnie to samo, wersja równoległa powinna być po prostu szybsza, ale jest o rząd wielkości wolniejsza. jakieś pomysły?

FYI zarówno d, jak i c są ogromnymi listami, zawierającymi od tysięcy do setek tysięcy elementów.

questionAnswers(2)

yourAnswerToTheQuestion