Here's something I'd do
It's mostly accurate, shouldn't show any CPS higher than the player's actual CPS, isn't 100% accurate though. Try it out, if it doesn't work, then try editing it and see what happens
on join:
while player is online:
set {cps::%player's uuid%} to floor({clicks::%player's uuid%}/3)
set {clicks::%player's uuid%} to 0
set tab list name of player to "%player% &7| &a%{cps::%player's uuid%}%&a CPS"
wait 3 seconds
on click:
set {clicks::%player's uuid%} to 0 if {clicks::%player's uuid%} is not set
add 1 to {clicks::%player's uuid%}
command /cps:
trigger:
send "&7Your CPS is: &l%{cps::%player's uuid%}%"
If you don't want to be spoonfed,
I'd say just make it so each time they click it adds to a variable and every x seconds it sets the cps to the clicks/x