Some benchmarks are measured with wrong approach
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 38/100
- Type d'issue
- Bug
- Clarté
- Plutôt claire
- Activité
- À l'abandon
- Stack technique
- ruby
- Domaine
- performance
Piste de recherche
Commencez par code/array/length-vs-size-vs-count.rb, le benchmark explicitement lié dans l’issue, et examinez ses blocs de rapport Benchmark.ips. Comparez l’approche actuelle fondée sur des blocs avec le format de rapport sous forme de chaîne de benchmark-ips décrit ici. Le travail est considéré comme terminé lorsque les benchmarks d’opérations courtes concernés utilisent l’approche présentant le moins d’overhead et que leurs résultats sont mis à jour ; l’issue n’énumère pas tous les fichiers concernés.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
tl;dr When we measure small things we have to remove all overheads which have impact. Wrapping with a method and block call is quite big overhead for most of benchmarks in this repository.
Suppose you want compare performance of "2 + 3" vs "2 * 3" calls. If you do it with a approach used in this repository you will get this results:
require "benchmark/ips"
def slow
2 * 2
end
def fast
2 + 2
end
Benchmark.ips do |x|
x.report("2 * 2") { slow }
x.report("2 + 2") { fast }
x.compare!
end
(simplified output)
Comparison:
2 + 2: 8304760.0 i/s
2 * 2: 7535516.6 i/s - 1.10x slower
But there is one problem. Calling a method + surrounding block ({ slow }) has bigger overhead than calling Fixnum#+ or Fixnum#* itself. Thea easiest way to observe it is to repeat benchmarked operations in one call. Like this:
require "benchmark/ips"
def slow
2*2; 2*2; 2*2; 2*2; 2*2; 2*2; 2*2; 2*2; 2*2; 2*2;
end
def fast
2+2; 2+2; 2+2; 2+2; 2+2; 2+2; 2+2; 2+2; 2+2; 2+2;
end
Benchmark.ips do |x|
x.report("2 * 2") { slow }
x.report("2 + 2") { fast }
x.compare!
end
Comparison:
2 + 2: 4680545.3 i/s
2 * 2: 3468681.3 i/s - 1.35x slower
See how results changed? Writing our benchmarks in this way would be quite problematic. Fortunately benchmark-ips gem has answer for that. Benchmark::IPS::Job#report method allows to pass string which will be compiled before benchmark is run. Passing right string allows to measure it properly:
require "benchmark/ips"
Benchmark.ips do |x|
x.report("2 * 2", "2 * 2;" * 1_000)
x.report("2 + 2", "2 + 2;" * 1_000)
x.compare!
end
Comparison:
2 + 2: 91567.5 i/s
2 * 2: 57994.4 i/s - 1.58x slower
This is greatly explained here: https://docs.omniref.com/ruby/2.2.1/symbols/Benchmark/bm#annotation=4095926&line=182
How does this affect fast-ruby benchmarks? All benchmarks that call small things are flawed. One of them is Array#length vs Array#size vs Array#count benchmark. Here is the original code and result obtained on my computer:
require 'benchmark/ips'
ARRAY = [*1..100]
Benchmark.ips do |x|
x.report("Array#length") { ARRAY.length }
x.report("Array#size") { ARRAY.size }
x.report("Array#count") { ARRAY.count }
x.compare!
end
Comparison:
Array#size: 8679483.2 i/s
Array#length: 8664450.7 i/s - 1.00x slower
Array#count: 7237299.5 i/s - 1.20x slower
The same benchmark measure with described approach gives different numbers:
require 'benchmark/ips'
ARRAY = [*1..100]
Benchmark.ips do |x|
x.report("Array#length", "ARRAY.length;" * 1_000)
x.report("Array#size", "ARRAY.size;" * 1_000)
x.report("Array#count", "ARRAY.count;" * 1_000)
x.compare!
end
Comparison:
Array#size: 113902.4 i/s
Array#length: 113655.9 i/s - 1.00x slower
Array#count: 28753.4 i/s - 3.96x slower
Difference: 1.20x slower vs 3.96x slower.
My guess is that it affects most of benchmarks.
- Langage dominant
- Ruby
- Étoiles
- 5.7k
- Forks
- 370
- Merge moyen
- 4 h 42 min
- PR mergées (30 j)
- 13
Préparer son environnement
- Fournit un Dockerfile ou un fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de fastruby/fast-ruby
-
Difficulté 2/5 1-3 heures Accessibilité débutants 52/100
fastruby/fast-ruby#230 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 35/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 45/100
fastruby/fast-ruby#220 · 6 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 42/100
fastruby/fast-ruby#208 · 7 commentaires · 1 réaction ·
Les mainteneurs répondent en général sous 1 jour
-
[FEATURE REQUEST] Use the project's WIKI to share results for each Ruby version with latest CI resultsPeut-être pris @JuanVqz l’a pris il y a 7 jours. Ouverte
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 30/100
fastruby/fast-ruby#206 · 4 commentaires · 1 réaction · 1 personne assignée ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de fastruby/fast-ruby
Issues similaires
-
Použiť Redis pre ActionCableOuverte
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
slovensko-digital/autogram-portal#392 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
voxpupuli/puppet-quadlets#122 · 5 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 82/100
TheOdinProject/curriculum#31452 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
-
revoir les metions de la DGEOuverte
Difficulté 1/5 Moins d'une heure Accessibilité débutants 72/100
betagouv/conseillers-entreprises#4720 ·
Les mainteneurs répondent en général sous 3 jours