Comments (8)
Whoaaa, there's sth srsly wrong with some of the methods accepting Char
, see this:
require "benchmark"
N = 10_000
str = "#{"x" * 100}/#{"y" * 100}@#{"z" * 100}"
Benchmark.ips do |x|
x.report("String#includes?(Char)") do
N.times { str.includes?('@') }
end
x.report("String#includes?(String)") do
N.times { str.includes?("@") }
end
end
String#includes?(Char) 63.03k ( 15.87µs) (± 3.61%) 0 B/op 5622.70× slower
String#includes?(String) 354.38M ( 2.82ns) (±16.05%) 0 B/op fastest
String#includes?
calls String#index
under-the-hood, which seems to be really under-optimized for Char
(calling String#each_char_with_index
which in turn calls String#each_char
, which creates an instance of CharIterator
). What's odd is that benchmarking String#index
shows difference of several magnitudes lower that String#includes?
...
from ameba.
Using a Char instead of String is not always better and it's impossible to detect automatically.
from ameba.
@straight-shoota could you please share an example when it is not better?
from ameba.
@straight-shoota I'm quite surprised but from a preliminary testing I just did it seems that in some cases using Char
is actually slower
Benchmark of String#index
for example:
String#index(Char) 206.8M ( 4.84ns) (±11.90%) 0 B/op 1.72× slower
String#index(String) 355.61M ( 2.81ns) (±14.81%) 0 B/op fastest
from ameba.
@Sija The difference of several magnitudes is very likely caused by an unintended performance optimization. 2.82 ns
is way to fast for 10.000 String#includes?(String)
calls, it's more likely the run time of only a single call.
Note that String#index(Char)
on a string with only ASCII characters (and the search character also being ASCII) does not use a each_char
but works directly on Slice#index
. Otherwise there would be some allocations for the CharIterator
.
from ameba.
The difference of several magnitudes is very likely caused by an unintended performance optimization.
2.82 ns
is way to fast for 10.000String#includes?(String)
calls, it's more likely the run time of only a single call.
Seems you're right, removing N.times {}
yields more understandable results:
String#includes?(Char) 231.21M ( 4.33ns) (±12.16%) 0 B/op 1.84× slower
String#includes?(String) 425.72M ( 2.35ns) (±13.37%) 0 B/op fastest
Note that
String#index(Char)
on a string with only ASCII characters (and the search character also being ASCII) does not use aeach_char
but works directly onSlice#index
. Otherwise there would be some allocations for theCharIterator
.
True that, although creating Slice
is still less performant than operating on a raw pointer as String#index(String)
does.
from ameba.
@Sija @straight-shoota what is your suggestion here? Should we force using char over string in some cases or not?
from ameba.
Closing this for now, @Sija be free to re-open for further discussion.
from ameba.
Related Issues (20)
- undefined constant Crystal::ThreadLocalValue on Windows HOT 4
- `Style/ParenthesesAroundCondition`: Redundant parentheses check assign. HOT 2
- Providing invalid config file path should raise instead of silently ignoring it HOT 1
- CyclomaticComplexity on SQL? HOT 2
- excludes files for all rules HOT 2
- Outdated docker hub image HOT 6
- Support Windows postinstall HOT 2
- Ameba seems to incorrectly show what the line that needs fixing is HOT 5
- Specs fail with Crystal 1.8.1 HOT 3
- Issue with Crystal Nightly HOT 12
- Installation failing on windows CI HOT 1
- [Feature request]: Json output HOT 1
- correctable error results in invalid crystal
- Excessive allocations
- Providing an invalid file path should raise instead of silently ignoring it HOT 7
- Error on macro expansion when building with Crystal 1.9.0 HOT 2
- Fails to install on MacOS Monterey HOT 2
- postinstall ameba 1.4.3 on Crystal 1.9.2 failed with: Error: type must be Ameba::Severity, not (Ameba::Severity | Nil) HOT 1
- `--only` CLI flag appears to ignore excluded files within config HOT 1
- BUG: trying to downcast (Slice(UInt8) | Nil) (Crystal::MixedUnionType) <- Slice(UInt8) (Crystal::GenericClassInstanceType) (Exception) HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ameba.