damirsvrtan / fasterer Goto Github PK
View Code? Open in Web Editor NEW:zap: Don't make your Rubies go fast. Make them go fasterer ™. :zap:
License: MIT License
:zap: Don't make your Rubies go fast. Make them go fasterer ™. :zap:
License: MIT License
I have a ruby project has a folder structure like,
token
token\token.rb
token\lib\base.rb
token\lib\parts.rb
...
I could not find a way to work fasterer on my project. It does work in my rails projects until receiving an error like,
"Fasterer was unable to process some files because the
internal parser is not able to read some characters or
has timed out. Unprocessable files were:"
I really liked the idea of this gem and want to use it, but maybe documentation is not enough or there is a problem using it on custom ruby projects. Thanks.
This probably shouldn't look at what's in vendor
, and arguably config
by default, yet I see no configuration option for limiting matches. Is that on the radar, or am I missing something?
Running the specs with Ruby 3.0, the following failures occur:
Failures:
1) Fasterer::Analyzer should detect gsub 4 times
Failure/Error: expect(analyzer.errors[:gsub_vs_tr].count).to eq(2)
expected: 2
got: 1
(compared using ==)
# ./spec/lib/fasterer/analyzer/24_gsub_vs_tr_spec.rb:9:in `block (2 levels) in <top (required)>'
Finished in 2.04 seconds (files took 0.78213 seconds to load)
92 examples, 1 failure, 1 pending
Failed examples:
rspec ./spec/lib/fasterer/analyzer/24_gsub_vs_tr_spec.rb:6 # Fasterer::Analyzer should detect gsub 4 times
-> Due to the current Ruby version restrictions (see also #84), this gem cannot be installed with Ruby 3. Restrictions are relaxed here: #85
Expectation: specs are not failing.
update: specs fixed in #85
Most of the hits I get are for plain string substitution...
ex., my_string.gsub('www.', 'dev.') # => replaces www. with dev.
Yes, I could move that trivial example into a regular expression just to avoid this suggestion, but what's the point in that?
The use of tr
is such that each character in the 1st argument is replaced by it's corresponding position in the 2nd argument. It isn't a simple find/replace on the entire string. So this suggestion by fasterer yields far too many false positives.
fasterer
advises to use each_key
instead of keys.each
even on objects that don’t support each_key
:
# keys_each.rb
class KeysProvider
def keys; []; end
end
kp = KeysProvider.new
kp.keys.each do |k|
puts k
end
$ fasterer keys_each.rb
keys_each.rb
Hash#keys.each is slower than Hash#each_key. Occurred at lines: 6.
This is a source code from my rails app models concern
# frozen_string_literal: true
module RecordNotUniqueHandler
extend ActiveSupport::Concern
included do
define_method :create_or_update do |*args|
super(*args)
rescue ActiveRecord::RecordNotUnique => e
attr_name, *scope = e.message
.match(/Key \(([^\)]+)\)/)[1].split(/,\s*/)
message = +(errors.generate_message(attr_name, :taken))
message << " (scope: #{scope.to_sentence})" if scope.any?
errors.add attr_name, message
false
end
end
end
fasterer outputs this error in the console
Fasterer was unable to process some files because the
internal parser is not able to read some characters or
has timed out. Unprocessable files were:
-----------------------------------------------------
app/models/concerns/record_not_unique_handler.rb - Racc::ParseError - (string):10 :: parse error on value ["rescue", 10] (kRESCUE)
Looks like it fails on this line rescue ActiveRecord::RecordNotUnique => e
Hey there.
I was wondering if support for specifying a list of files to run Fasterer on could be added.
It would be really nice if we could make it work with xargs, I had this use case in mind:
echo app/controllers/application_controller.rb config/routes.rb | xargs bundle exec fasterer
Currently it is possible to either:
It would be nice to be able to fine-tune the configuration, similar to these:
I have play fasterer
in my code.It point out Using module_eval is slower than define_method. Occured at lines: 50.
.But my code is something like that:
class Thing
@foo = 'test'
end
Thing.module_eval {puts @foo}
It can not be changed to define_method
in this situation.So, it think it should not give me the suggestion anywhere I using module_eval
.
NOTE: RubyParser::V25 undefined, using RubyParser::V24
When I run
$ fasterer
in my Rails project, I get this error.
Fasterer was unable to process some files because the
internal parser is not able to read some characters.
Unprocessable files were:
-----------------------------------------------------
config/initializers/wrap_parameters.rb
The file has nothing but the default comments at the top. I would expect it to just skip this file.
bundle exec fasterer
/home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/ruby_parser-3.7.2/lib/ruby_parser_extras.rb:1393:in `for_current_ruby': unrecognized RUBY_VERSION 2.3.0 (RuntimeError)
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/parser.rb:8:in `parse'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/analyzer.rb:21:in `scan'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/file_traverser.rb:58:in `scan_file'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/file_traverser.rb:50:in `block in traverse_files'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/file_traverser.rb:50:in `each'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/file_traverser.rb:50:in `traverse_files'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/file_traverser.rb:27:in `traverse'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/lib/fasterer/cli.rb:7:in `execute'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/gems/fasterer-0.3.1/bin/fasterer:5:in `<top (required)>'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/bin/fasterer:23:in `load'
from /home/ubuntu/optimize_it/vendor/bundle/ruby/2.3.0/bin/fasterer:23:in `<main>' bundle exec fasterer returned exit code 1
Detect Enumerable#select + last, suggest Array#reverse + detect
This would make the integration with editors like VSCode way easier. Something like fasterer file.rb
would be great.
Hi, very nice program here 👍. Just started using it and, being very familiar with the fast-ruby benchmarks, I thought that I would be nice to have RUBY_ENGINE
specific suggestions.
I know you have your disclaimer -and certainly we should not blindly do whatever the machine tells us, but in the case of JRuby (maybe others) some of the suggestions are counterintuitive to what most people think is "fast ruby". Tailoring suggestions for the platform could be very helpful.
Thoughts?
Hello!
I work on some rather large codebases, and running the very cool fasterer
on them results in more information than is humanly manageable. It would be nice if I could run it on a single file (the one I'm working on). i.e.
$ fasterer app/controllers/users_controller.rb
Thanks,
Louis
Hi,
I was trying to use fasterer on a single .rb file:
fasterer wlan.rb
I get the following error message:
Fasterer was unable to process some files because the
internal parser is not able to read some characters or
has timed out. Unprocessable files were:
wlan.rb
This error message does not tell me much. What are the
bad characters? Why can it not process?
For reference, the file wlan.rb is available at:
Let's say we're creating something like Rails' indifferent access for hashes:
> cat foo.rb
def my_with_indifferent_access(hash)
hash.keys.each do |k|
hash[k.to_sym] = hash[k] if k.is_a?(String)
end
hash
end
puts my_with_indifferent_access({ 'a' => 1 })[:a]
> ruby foo.rb
1
fasterer 0.3.2
says
Hash#keys.each is slower than Hash#each_key. Occurred at lines: 2.
but making that change gives a runtime error:
> ruby foo.rb
foo.rb:3:in `block in my_with_indifferent_access': can't add a new key into hash during iteration (RuntimeError)
from foo.rb:2:in `each_key'
from foo.rb:2:in `my_with_indifferent_access'
from foo.rb:9:in `<main>'
While it would be great if fasterer
could inspect the block of the each
and attempt to determine if the hash is modified during the iteration (not outputting the warning if so), this isn't possible in general. Furthermore, looking at the current implementation, it doesn't look like any of the necessary context is available where the warning is raised.
A better solution might be to explicitly warn that blindly replacing keys.each
with each_key
is not safe in general, perhaps something like:
Hash#keys.each is slower than Hash#each_key. N.B. 'Hash#each_key' cannot be used if the hash is modified during the
eachblock. Occurred at lines: 2.
It doesn't seem faster when I tested:
Rehearsal -------------------------------------------------------------
hash with second argument 1.460000 0.010000 1.470000 ( 1.504500)
hash with block 1.570000 0.010000 1.580000 ( 1.575685)
---------------------------------------------------- total: 3.050000sec
user system total real
hash with second argument 1.210000 0.000000 1.210000 ( 1.216288)
hash with block 1.580000 0.000000 1.580000 ( 1.583985)
› ruby --version
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
Test Code:
require 'benchmark'
require 'json'
$hash = {}
COUNTER = 5000000
Benchmark.bmbm do |repo|
repo.report("hash with second argument") do
0.upto(COUNTER) { $hash.fetch('moshe', 'default') }
end
repo.report("hash with block") do
0.upto(COUNTER) { $hash.fetch('moshe') {'default' } }
end
end
Maybe it is something related to older version of ruby?
Hey there, I can see, that there are some PRs and that the code haven't been updated for quite a while. Just wanted to know, whether or not it is still maintained.
I have a ActiveRecord statement like .
..select('code').first
Fasterer surfaces that as being optimizable to detect. I believe that is incorrect. It does not appear to recognize only selects that use a predicate.
I've run into 2 issues with the Block vs Symbol to Proc offense.
numbers.each { |number| number.to_s }
but, this is not flagged:
numbers = [1, 2, 3, 4, 5]
numbers.each { |number| number.to_s }
Both have the same each block, but the parser dismisses it once the previous code is added.
numbers.map { |number| number.to_s }
or
numbers.any? { |number| number.even? }
Hi! First, thanks so much for fasterer
-- it's super helpful!
I wanted to report a false-positive finding that I noticed. When using a Redis client, I'm using its keys
method, which lists the names of the Redis server's keys. At least in this case, Fasterer makes a recommendation based on an incorrect presumption that the receiver is a Hash
, not a Redis connection handle.
$ cat > foo.rb
@redis.keys('queue:*').each do |queue_name|
puts queue_name
end
^D
$ bundle exec fasterer foo.rb
foo.rb:1 Hash#keys.each is slower than Hash#each_key. N.B. Hash#each_key cannot be used if the hash is modified during the each block.
1 file inspected, 1 offense detected
$ fasterer
app/controllers/data/charts_controller.rb
For loop is slower than using each. Occured at lines: 76, 87, 90, 102, 206, 240.
app/controllers/data_controller.rb
For loop is slower than using each. Occured at lines: 119, 146, 147.
app/models/country.rb
For loop is slower than using each. Occured at lines: 22, 26.
app/models/event.rb
For loop is slower than using each. Occured at lines: 445, 459, 472, 486, 498, 614.
app/models/user.rb
Calling argumentless methods within blocks is slower than using symbol to proc. Occured at lines: 21, 31.
/Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_lexer.rex.rb:288:in `scan': execution expired (Timeout::Error)
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_lexer.rex.rb:288:in `next_token'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_parser_extras.rb:919:in `next_token'
from /Users/dan/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/racc/parser.rb:258:in `_racc_do_parse_c'
from /Users/dan/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/racc/parser.rb:258:in `do_parse'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_parser_extras.rb:1036:in `block in process'
from /Users/dan/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:89:in `block in timeout'
from /Users/dan/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:34:in `block in catch'
from /Users/dan/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:34:in `catch'
from /Users/dan/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:34:in `catch'
from /Users/dan/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:104:in `timeout'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_parser_extras.rb:1024:in `process'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_parser_extras.rb:1357:in `block in process'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_parser_extras.rb:1355:in `each'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/ruby_parser-3.6.4/lib/ruby_parser_extras.rb:1355:in `process'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/parser.rb:8:in `parse'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/analyzer.rb:21:in `scan'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/file_traverser.rb:56:in `scan_file'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/file_traverser.rb:67:in `block in traverse_directory'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/file_traverser.rb:64:in `each'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/file_traverser.rb:64:in `traverse_directory'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/file_traverser.rb:27:in `traverse'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/lib/fasterer/cli.rb:7:in `execute'
from /Users/dan/.rvm/gems/ruby-2.2.0/gems/fasterer-0.1.7/bin/fasterer:5:in `<top (required)>'
from /Users/dan/.rvm/gems/ruby-2.2.0/bin/fasterer:23:in `load'
from /Users/dan/.rvm/gems/ruby-2.2.0/bin/fasterer:23:in `<main>'
from /Users/dan/.rvm/gems/ruby-2.2.0/bin/ruby_executable_hooks:15:in `eval'
from /Users/dan/.rvm/gems/ruby-2.2.0/bin/ruby_executable_hooks:15:in `<main>'
Hash.update is an alias for Hash.merge!
Currently we have hash_merge_bang_vs_hash_brackets
which suggests us to replace Hash#merge!() with Hash#[] but it doesn't suggest for Hash#update().
Example
Can we extend this to Hash.update()?
It'd be nice to have JSON output, maybe something like --format
json or even --json
. This would make the integration with editors like VSCode way easier.
I think it would be a great enhancement if I was able to disable/exclude a speed suggestion for a specific line via a magic comment (much like how Rubocop does single-instance cop-disablement; # rubocop:disable Metrics/LineLength
).
There are times where a single speedup
in a given line of code is not applicable and I want to disable the speedup
for the line but I don't want to have to add the entire file to the exclude_paths
block of .fasterer.yml
.
For example, if I have instance whereby I've used Hash#keys.each
two times in a single file and one of those two times the hash is modified during the .each
block (but the other time, the hash is not modified during the .each
block) then I would want fasterer
to ignore that singular instance of Hash#keys.each
where the hash is modified (while still letting fasterer
analyze the other instance of Hash#keys.each
where the hash is not modified).
Hopefully this makes sense and seems reasonable!
Thanks for all the work put into fasterer
over the years; it has certainly made some of my code... well... fasterer
. 😄
$ fasterer /usr/lib/ruby/2.7.0/matrix.rb
NOTE: RubyParser::V27 undefined, using RubyParser::V26.
Fasterer was unable to process some files because the
internal parser is not able to read some characters or
has timed out. Unprocessable files were:
-----------------------------------------------------
/usr/lib/ruby/2.7.0/matrix.rb - Racc::ParseError - (string):2256 :: parse error on value "," (tCOMMA)
1 file inspected, 0 offenses detected, 1 unparsable file found
Rubocop has an auto correct method. It would be nice to see something similar within fasterer (with an appropriate warning)
It is widely accepted by CI services to integrate with their UI. I think it'd be nice. I'd like it to be used this way:
bundle exec fasterer --format junit --output fasterer.xml
Thanks, keep up the good work.
From rails/rails#26599 i'm seeing that's not the case. Btw, this is a really cool project.
cc/ @timrogers
Running this code:
#!/usr/bin/env ruby
require 'benchmark/ips'
ARR1 = [ 1, 2, 3 ] * 1_000_000
Benchmark.ips do |b|
b.report('.reverse.first') do
ARR1.reverse.first(1_000)
end
b.report('.last.reverse') do
ARR1.last(1_000).reverse
end
b.compare!
end
Benchmark.ips do |b|
b.report('.reverse.last') do
ARR1.reverse.last(1_000)
end
b.report('.first.reverse') do
ARR1.first(1_000).reverse
end
b.compare!
end
we see a huge speed difference for this simple synthetic benchmark:
Calculating -------------------------------------
.reverse.first 24 i/100ms
.last.reverse 80711 i/100ms
-------------------------------------------------
.reverse.first 153.7 (±3.3%) i/s - 792 in 5.157104s
.last.reverse 1155593.4 (±2.0%) i/s - 5811192 in 5.030946s
Comparison:
.last.reverse: 1155593.4 i/s
.reverse.first: 153.7 i/s - 7516.20x slower
Calculating -------------------------------------
.reverse.last 25 i/100ms
.first.reverse 83388 i/100ms
-------------------------------------------------
.reverse.last 259.5 (±4.6%) i/s - 1300 in 5.022875s
.first.reverse 1050525.6 (±8.4%) i/s - 5253444 in 5.047410s
Comparison:
.first.reverse: 1050525.6 i/s
.reverse.last: 259.5 i/s - 4048.21x slower
It's pretty intuitive that it works this way:
Let's say our array has N elements, and we want the last n but reversed.
We can either reverse it first, making N swaps (i.e. copies) and then copy the first n elements, making N+n copies, or we can take the last n elements, making n copies and then swap them n times, performing 2*n copies.
I'm working in a detector for these opportunities, but I don't know if I'll make it.
I seems there is a bug in support for interpolated array of symbols separated by whitespace (Ruby > 2.X)
test.rb
file:#!/usr/bin/env ruby
puts %I[#{42}].inspect
Code works:
> ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
> ruby test.rb
[:"42"]
fasterer
parser error:> fasterer test.rb
~/.gem/ruby/2.4.2/gems/ruby_parser-3.10.1/lib/ruby_parser_extras.rb:23:in `debug20': not yet 24 nil => nil (RuntimeError)
from ~/.gem/ruby/2.4.2/gems/ruby_parser-3.10.1/lib/ruby_parser_extras.rb:883:in `new_symbol_list_entry'
from ~/.gem/ruby/2.4.2/gems/ruby_parser-3.10.1/lib/ruby24_parser.rb:5950:in `_reduce_467'
from ~/.rubies/ruby-2.4.2/lib/ruby/2.4.0/racc/parser.rb:259:in `_racc_do_parse_c'
from ~/.rubies/ruby-2.4.2/lib/ruby/2.4.0/racc/parser.rb:259:in `do_parse'
from ~/.gem/ruby/2.4.2/gems/ruby_parser-3.10.1/lib/ruby_parser_extras.rb:1087:in `block in process'
from ~/.rubies/ruby-2.4.2/lib/ruby/2.4.0/timeout.rb:93:in `block in timeout'
from ~/.rubies/ruby-2.4.2/lib/ruby/2.4.0/timeout.rb:33:in `block in catch'
from ~/.rubies/ruby-2.4.2/lib/ruby/2.4.0/timeout.rb:33:in `catch'
from ~/.rubies/ruby-2.4.2/lib/ruby/2.4.0/timeout.rb:33:in `catch'
from ~/.rubies/ruby-2.4.2/lib/ruby/2.4.0/timeout.rb:108:in `timeout'
from ~/.gem/ruby/2.4.2/gems/ruby_parser-3.10.1/lib/ruby_parser_extras.rb:1075:in `process'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/parser.rb:8:in `parse'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/analyzer.rb:21:in `scan'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/file_traverser.rb:57:in `scan_file'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/file_traverser.rb:49:in `block in traverse_files'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/file_traverser.rb:49:in `each'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/file_traverser.rb:49:in `traverse_files'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/file_traverser.rb:26:in `traverse'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/lib/fasterer/cli.rb:7:in `execute'
from ~/.gem/ruby/2.4.2/gems/fasterer-0.3.2/bin/fasterer:5:in `<top (required)>'
from ~/.gem/ruby/2.4.2/bin/fasterer:23:in `load'
from ~/.gem/ruby/2.4.2/bin/fasterer:23:in `<main>'
I just installed fasterer 0.8.1 and got the following error on running it:
% fasterer
app/models/freelancers/freelancer.rb:149 Array#reverse.each is slower than Array#reverse_each.
app/models/concerns/has_phone_numbers.rb:100 Using tr is faster than gsub when replacing a single character in a string with another single character.
app/dashboards/freelancers/freelancer_dashboard.rb:102 Hash#keys.each is slower than Hash#each_key. N.B. Hash#each_key cannot be used if the hash is modified during the each block.
app/controllers/admin/freelancers_controller.rb:137 Array#select.last is slower than Array#reverse.detect.
Traceback (most recent call last):
34: from /Users/manuel/.rbenv/versions/2.6.5/bin/fasterer:23:in `<main>'
33: from /Users/manuel/.rbenv/versions/2.6.5/bin/fasterer:23:in `load'
32: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/bin/fasterer:5:in `<top (required)>'
31: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/cli.rb:7:in `execute'
30: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/file_traverser.rb:26:in `traverse'
29: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/file_traverser.rb:49:in `traverse_files'
28: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/file_traverser.rb:49:in `each'
27: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/file_traverser.rb:49:in `block in traverse_files'
26: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/file_traverser.rb:57:in `scan_file'
25: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:22:in `scan'
24: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `traverse_sexp_tree'
23: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `each'
22: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `block in traverse_sexp_tree'
21: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `traverse_sexp_tree'
20: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `each'
19: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `block in traverse_sexp_tree'
18: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `traverse_sexp_tree'
17: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `each'
16: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `block in traverse_sexp_tree'
15: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `traverse_sexp_tree'
14: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `each'
13: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `block in traverse_sexp_tree'
12: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `traverse_sexp_tree'
11: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `each'
10: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `block in traverse_sexp_tree'
9: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `traverse_sexp_tree'
8: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `each'
7: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:45:in `block in traverse_sexp_tree'
6: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:36:in `traverse_sexp_tree'
5: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:54:in `scan_by_token'
4: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:71:in `scan_method_calls'
3: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/analyzer.rb:71:in `new'
2: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/scanners/method_call_scanner.rb:13:in `initialize'
1: from /Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/scanners/method_call_scanner.rb:48:in `check_offense'
/Users/manuel/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fasterer-0.8.1/lib/fasterer/scanners/method_call_scanner.rb:135:in `check_symbol_to_proc': undefined method `name' for #<Fasterer::Primitive:0x00007f9a2092afd8> (NoMethodError)
With this example code:
(1..100).select { |i| i >= 50 }.first(5)
fasterer 0.10.0
reports Array#select.first is slower than Array#detect.
.
However, this is only true when Enumerable#first
takes no argument; here we want the first 5 matching elements and detect does not support that functionality.
I suggest that this detector only fires when first
is passed no argument
Did 0.8.3
version really requires ruby ~> 2.2
? Can this requirements relaxed to >= 2.2
?
Got Racc::ParseError - (string):3 :: parse error on value "=" (tEQL)
Code example that break execution:
module ToBoolean
refine Object do
def to_bool = ActiveRecord::Type::Boolean.new.cast(self)
end
refine TrueClass do
def to_bool = self
end
refine FalseClass do
def to_bool = self
end
refine NilClass do
def to_bool = self
end
refine Numeric do
def to_bool = !zero?
end
end
We have several ruby projects in one repo. We'd like to have the yml file in the root.
Would you be open to a change to have an upwards traversal to find it?
I believe the latest results from fast-ruby show that Parallel assignment is faster than sequential assignmnent. I ran benchmarks on my own code as well and sequential assignment is reported as slower. Currently, fasterer is saying that Parallel assignment is slower than sequential assignment.
, which I believe is wrong.
fasterer
NOTE: RubyParser::V26 undefined, using RubyParser::V25.
@DamirSvrtan any chance to get support for Ruby 3.1.0? Seems like the project https://github.com/seattlerb/ruby_parser isn't maintained anymore
when running fasterer I get:
bundler: failed to load command: fasterer (/home/mencio/.rbenv/versions/2.6.5/bin/fasterer)
Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT
gems/ruby_parser-3.14.0/lib/ruby_lexer.rex.rb:163:in `gsub'
gems/ruby_parser-3.14.0/lib/ruby_lexer.rex.rb:163:in `block in next_token'
gems/ruby_parser-3.14.0/lib/ruby_lexer.rex.rb:68:in `action'
gems/ruby_parser-3.14.0/lib/ruby_lexer.rex.rb:163:in `next_token'
gems/ruby_parser-3.14.0/lib/ruby_parser_extras.rb:1266:in `next_token'
/home/mencio/.rbenv/versions/2.6.5/lib/ruby/2.6.0/racc/parser.rb:259:in `_racc_do_parse_c'
/home/mencio/.rbenv/versions/2.6.5/lib/ruby/2.6.0/racc/parser.rb:259:in `do_parse'
gems/ruby_parser-3.14.0/lib/ruby_parser_extras.rb:1301:in `block in process'
/home/mencio/.rbenv/versions/2.6.5/lib/ruby/2.6.0/timeout.rb:93:in `block in timeout'
/home/mencio/.rbenv/versions/2.6.5/lib/ruby/2.6.0/timeout.rb:33:in `block in catch'
/home/mencio/.rbenv/versions/2.6.5/lib/ruby/2.6.0/timeout.rb:33:in `catch'
/home/mencio/.rbenv/versions/2.6.5/lib/ruby/2.6.0/timeout.rb:33:in `catch'
/home/mencio/.rbenv/versions/2.6.5/lib/ruby/2.6.0/timeout.rb:108:in `timeout'
gems/ruby_parser-3.14.0/lib/ruby_parser_extras.rb:1289:in `process'
gems/fasterer-0.7.1/lib/fasterer/parser.rb:8:in `parse'
gems/fasterer-0.7.1/lib/fasterer/analyzer.rb:21:in `scan'
gems/fasterer-0.7.1/lib/fasterer/file_traverser.rb:57:in `scan_file'
gems/fasterer-0.7.1/lib/fasterer/file_traverser.rb:49:in `block in traverse_files'
gems/fasterer-0.7.1/lib/fasterer/file_traverser.rb:49:in `each'
gems/fasterer-0.7.1/lib/fasterer/file_traverser.rb:49:in `traverse_files'
gems/fasterer-0.7.1/lib/fasterer/file_traverser.rb:26:in `traverse'
gems/fasterer-0.7.1/lib/fasterer/cli.rb:7:in `execute'
gems/fasterer-0.7.1/bin/fasterer:5:in `<top (required)>'
/home/mencio/.rbenv/versions/2.6.5/bin/fasterer:23:in `load'
/home/mencio/.rbenv/versions/2.6.5/bin/fasterer:23:in `<top (required)>'
repro:
git clone https://github.com/mensfeld/broken-fasterer.git
cd broken-fasterer
./run.sh
👋Hi
With this output, we can faster go to files directly in line.
I checked in RubyMine and Sublime Text, Visual Studio Code, also it works in vim.
Output:
code.rb:5 Using each_with_index is slower than while loop.
code.rb:21 Using each_with_index is slower than while loop.
code.rb:37 Enumerable#sort is slower than Enumerable#sort_by.
What do you think about this? If you like it I can do it :)
Report with links will be more informative.
lib/code.rb:9 Use attr_reader for reading ivars [https://github.com/DamirSvrtan/fasterer/docs/attr_reader_vs_ivars.md]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.