I'd be interested to see your benchmark (code + data), as I don't come to the same conclusion.
Test and output attached below. Looks like it is dependent on your data set...
use strict;
use Benchmark 'cmpthese';
my @data = <DATA>;
my @long = map { join '', $_ x 100 } @data;
my %cases = (
'Single' => sub { for ( @long ) { /^\w+(?:,\w+)*$/ } },
'Double' => sub { for ( @long ) { /^[\w,]+$/ && ! /^,|,,|,$/ } },
);
cmpthese( 0, \%cases);
__DATA__
!@#$as3dfa
,sdfas3df,
asd3fsa,,a3sdf
as3df,asdf3,3asdf,asd3f
sad3fasdjasdfkasdfklas3jf
3sad3fasdjasdfkasdfklas3jf
3sad3fasdjasdfkasdfklas3jf3
Rate Single Double
Single 6158/s -- -83%
Double 35319/s 474% --