There is more to this question than it may seem.
Simple version
This is much faster and simpler:
SELECT property_name
      ,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM   my_obj
GROUP  BY 1;
Result:
property_name | pct
--------------+----
 prop_1       | 17
 prop_2       | 43
How?
- You don't need a function for this at all.  
- Instead of counting - value_b(which you don't need to begin with) and calculating the total, use- count(*)for the total. Faster, simpler.
 
- This assumes you don't have - NULLvalues. I.e. both columns are defined- NOT NULL. The information is missing in your question.
 If not, your original query is probably not doing what you think it does. If any of the values is NULL, your version does not count that row at all. You could even provoke a division-by-zero exception this way.
 This version works with NULL, too.- count(*)produces the count of all rows, regardless of values.
 
- Here's how the count works: -  TRUE  OR NULL = TRUE
 FALSE OR NULL = NULL
 - count()ignores NULL values. Voilá.
 
- Operator precedence governs that - =binds before- OR. You could add parentheses to make it clearer:
 - count ((value_a = value_b) OR FALSE)
 
- You can do the same with  - count NULLIF(<expression>, FALSE)
 
- The result type of - count()is- bigintby default.
 A division- bigint / bigint, truncates fractional digits.
 
Include fractional digits
Use 100.0 (with fractional digit) to force the calculation to be numeric and thereby preserve fractional digits.
You may want to use round() with this:
SELECT property_name
      ,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM   my_obj
GROUP  BY 1;
Result:
property_name | pct
--------------+-------
 prop_1       | 17.23
 prop_2       | 43.09
As an aside:
I use value_a instead of valueA. Don't use unquoted mixed-case identifiers in PostgreSQL. I have seen too many desperate question coming from this folly. If you wonder what I am talking about, read the chapter Identifiers and Key Words in the manual.