From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) 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_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_MED,SPF_PASS,T_DKIM_INVALID, T_RP_MATCHES_RCVD shortcircuit=no autolearn=ham autolearn_force=no version=3.4.0 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id 68F9E20282 for ; Fri, 16 Jun 2017 07:57:26 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 2CC4512078F; Fri, 16 Jun 2017 16:57:24 +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 A54E0120788 for ; Fri, 16 Jun 2017 16:57:22 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=sendgrid.me; h=from:to:references:subject:mime-version:content-type:content-transfer-encoding:list-id; s=smtpapi; bh=MWR2xgg2FRH+Q4CO9z00SA5Aowg=; b=g0klh41ZulPefBDqv0 BVJm2BCPVTGJb587xbXcPL0ZRDK6xhHD1bPbPPB5SlsFJ7QT4L5SkUYnorwAQDqm tb7XBSucLwef9vjtuNcCq+y4XKERJE/GSiTXKI7bKbTp23QQCCt60ZYWcV8ndbyj +QF+cAptq0YCKhkGxiFFDb7pQ= Received: by filter0476p1mdw1.sendgrid.net with SMTP id filter0476p1mdw1-31171-59438F5C-49 2017-06-16 07:57:16.867670525 +0000 UTC Received: from herokuapp.com (ec2-54-166-169-114.compute-1.amazonaws.com [54.166.169.114]) by ismtpd0002p1iad1.sendgrid.net (SG) with ESMTP id sMxHC6xmQ32dyg3co_3I_w Fri, 16 Jun 2017 07:57:16.780 +0000 (UTC) Date: Fri, 16 Jun 2017 07:57:16 +0000 From: ko1@atdot.net To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 56730 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 13378 X-Redmine-Issue-Author: burke X-Redmine-Issue-Assignee: nobu X-Redmine-Sender: ko1 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/Ymy4QrNMhiuLXJG8OTL2vJD1yS5TUDerCiP94sH4jgYDstGytGsHYU6UBOuqJc M/VSI0lDRvVz0in2kyi7OR8llhO3XabnJoBm4bXiiwjFjMghkGCy8ctu4++kc5Z5KwOtopG4kH3nFK AYToeoVfpn4x2F24RH+24v6PbKhFVAoiEuFl X-ML-Name: ruby-core X-Mail-Count: 81702 Subject: [ruby-core:81702] [Ruby trunk Feature#13378] Eliminate 4 of 8 syscalls when requiring file by absolute path 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 #13378 has been updated by ko1 (Koichi Sasada). Assignee set to nobu (Nobuyoshi Nakada) ---------------------------------------- Feature #13378: Eliminate 4 of 8 syscalls when requiring file by absolute path https://bugs.ruby-lang.org/issues/13378#change-65392 * Author: burke (Burke Libbey) * Status: Open * Priority: Normal * Assignee: nobu (Nobuyoshi Nakada) * Target version: ---------------------------------------- Don't open file twice when specified by absolute path. When invoking `require '/a.rb'` (i.e. via an absolute path), ruby generates this sequence of syscalls: open /a.rb fstat64 /a.rb close /a.rb open /a.rb fstat64 /a.rb fstat64 /a.rb read /a.rb close /a.rb It is apparent that the only inherently necessary members of this sequence are: open /a.rb fstat64 /a.rb read /a.rb close /a.rb (the fstat64 isn't *obviously* necessary, but it does serve a purpose and probably shouldn't be removed). The first open/fstat64/close is used to check whether the file is loadable. This is important when scanning the `$LOAD_PATH`, since it is used to determine when a file has been found. However, when we've already unambiguously identified a file before invoking `require`, this serves no inherent purpose, since we can move whatever work is happening as a result of that `fstat64` into the second open/close sequence. This change bypasses the first open/fstat64/close in the case of an absolute path to `require`. It also removes one of the doubled-up `fstat64` calls later in the sequence. As a result, the number of syscalls to require a file changes: * From 8 to 4 when specified by absolute path; * From 5+3n to 4+3n otherwise *(where n is the number of `$LOAD_PATH` items scanned)*. In future work, it would be possible to re-use the file descriptor opened while searching the `$LOAD_PATH` without the close/open sequence, but this would cause some ugly layering issues. --- *We intend to use this in conjunction with something like https://github.com/shopify/bootscale, which pre-resolves required features to absolute paths before calling `require`. This change reduces our total number of filesystem accesses by 13% during application boot.* *Various notes and rationale at http://notes.burke.libbey.me/ruby-require-optimization* ---Files-------------------------------- 0001-reduce-syscalls-on-require.patch (7.56 KB) 0001-reduce-syscalls-on-require-fixed.patch (6.94 KB) 0001-reduce-syscalls-on-require-v2.patch (6.44 KB) -- https://bugs.ruby-lang.org/