Yola
Yola

Reputation: 19043

Why so big difference in GC time in two implementations

have two algorithm implementations:

average(List) -> sum(List) / len(List).

sum([]) -> 0;
sum([Head | Tail]) -> Head + sum(Tail).

len([]) -> 0;
len([_ | Tail]) -> 1 + len(Tail).



average1(List) -> average_acc(List, 0,0).

average_acc([], Sum, Length) -> Sum / Length;
average_acc([H | T], Sum, Length) -> average_acc(T, Sum + H, Length + 1).

and output for trace GC events gc_start gc_end (gc started and stopped):

here every next value for process is a sum of preceding value and last gc time

average: 5189 average: 14480 average: 15118

average1: 594

Why so big difference?

PS. I use wall clock time.

Upvotes: 0

Views: 170

Answers (1)

Hynek -Pichi- Vychodil
Hynek -Pichi- Vychodil

Reputation: 26121

  1. You should not use wall clock time (timestamp flag) to measure what GC takes because even GC is not rescheduled in Erlang scheduler thread the thread self can be rescheduled by underlying OS. So you should use cpu_timestamp instead.
  2. Your average/1 is using sum/1 and count/1 implementation where both are not tail recursive so you allocate 2*N stack frames which makes big difference in performance to average1/1 which uses tail recursive average_acc/3. So average1/1 performs exactly as loop in other languages.

Edit:

  1. Edited according Yola stated he is using timestamp flag for trace messages.

Upvotes: 2

Related Questions