From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS4713 221.184.0.0/13 X-Spam-Status: No, score=-3.0 required=3.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FORGED_GMAIL_RCVD,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id D619B211B3 for ; Wed, 5 Dec 2018 04:27:03 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id B6E57120E3B; Wed, 5 Dec 2018 13:27:02 +0900 (JST) Received: from o1678916x28.outbound-mail.sendgrid.net (o1678916x28.outbound-mail.sendgrid.net [167.89.16.28]) by neon.ruby-lang.org (Postfix) with ESMTPS id C5CDC120E39 for ; Wed, 5 Dec 2018 13:27:00 +0900 (JST) Received: by filter0036p3las1.sendgrid.net with SMTP id filter0036p3las1-7469-5C075392-2B 2018-12-05 04:26:58.940627345 +0000 UTC m=+122285.548874184 Received: from herokuapp.com (ec2-54-91-83-26.compute-1.amazonaws.com [54.91.83.26]) by ismtpd0036p1iad2.sendgrid.net (SG) with ESMTP id -A3GQGSnSheZ8CrccZPS9g for ; Wed, 05 Dec 2018 04:26:58.805 +0000 (UTC) Date: Wed, 05 Dec 2018 04:26:59 +0000 (UTC) From: fursich0@gmail.com To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 65687 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 15380 X-Redmine-Issue-Author: fursich X-Redmine-Sender: fursich X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS4Z9vSHFGFnRAXYb67Yrs5t0VASyOOWjz5Gaa SFrdAYBDf4A8NV8+65OR4jpCrZNUMFSrRG4uySjg5pyUkURVB7qs4yq3nSlcgWfuLCUThu6MgLEQWG msrVLmE7wgmN7fv9lFo7xdCmatGAOb2tMFI2Ry5cj3ioVFjT2JIYerzU2g== X-ML-Name: ruby-core X-Mail-Count: 90294 Subject: [ruby-core:90294] [Ruby trunk Feature#15380] faster method lookup for Array#all? #none? #one? X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #15380 has been reported by fursich (Onishi Koji). ---------------------------------------- Feature #15380: faster method lookup for Array#all? #none? #one? https://bugs.ruby-lang.org/issues/15380 * Author: fursich (Onishi Koji) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- ## summary This PR proposes Array-specific implementations for `#all?` , `#none?` and `#one?` to enable faster method lookup. Before this patch `Array#all?` was not implemented in Array class, so alternatively, `Enumerable#all?` was used each time the method is called. On the other hand, `#any?` has its own method entry in Array class for faster method calls. This patch provides above three methods with Array-specific implementations that are equivalent to what `Array#any?` has. https://github.com/ruby/ruby/pull/2041 ## benchmark ~~~ text ********************************************************************************** benchmarking Array#all? ********************************************************************************** Calculating ------------------------------------- Array#all? (new) 421.298 i/s - 1.000k times in 2.373616s (2.37ms/i) Array#all? (old) 335.364 i/s - 1.000k times in 2.981838s (2.98ms/i) Comparison: Array#all? (new): 421.3 i/s Array#all? (old): 335.4 i/s - 1.26x slower Calculating ------------------------------------- Array#all? (new) 244.929 i/s - 1.000k times in 4.082823s (4.08ms/i) Array#all? (old) 210.354 i/s - 1.000k times in 4.753895s (4.75ms/i) Comparison: Array#all? (new): 244.9 i/s Array#all? (old): 210.4 i/s - 1.16x slower ~~~ Attached benchmark shows the full benchmark results: https://gist.github.com/fursich/1d1bad353ddc2f4b510b34e3191fd302 Each method gets approx. 10-20% faster with repeated calls. It only impacts on method lookup (not execution itself), but at least it should make` Array#all?` work as just efficiently as `Array#any?` does. ## estimate of impact Just to provide a rough picture on how frequently these methods are used in real world app, here shows a quick-and-dirty investigations I did with [rails](https://github.com/rails/rails) (using its latest master as of Dec 5): ~~~ text rails (master)$ git grep '\.all?' | wc -l 80 rails (master)$ git grep '\.one?' | wc -l 13 rails (master)$ git grep '\.none?' | wc -l 25 ~~~ while ~~~ text rails (master)$ git grep '\.any?' | wc -l ~~~ (* the result includes non-Array method. the intention here is just to give rough estimate on how frequently these methods are used compared with each other) It's probably fair to say the use of the three methods (118 lines in total here) are *not* ignorably rare compared to `#all?` ## motivation behind it In developing Ruby apps we encounter (often non essential) discussion around 'which method call is faster?', 'should we use this method for efficiency?'. As Ruby lover I really hope to pick methods based on pure readability and Ruby-ness, Hopefully it helps Ruby become faster even at slightest level :) -- https://bugs.ruby-lang.org/