From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (smtp.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id 3EB721B61F95 for ; Wed, 29 Mar 2017 04:55:26 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id 8EF0FB5D819 for ; Wed, 29 Mar 2017 05:31:35 +0900 (JST) Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id A834318CC819 for ; Wed, 29 Mar 2017 05:31:35 +0900 (JST) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 4CEB1120709; Wed, 29 Mar 2017 05:31:33 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from o1678948x4.outbound-mail.sendgrid.net (o1678948x4.outbound-mail.sendgrid.net [167.89.48.4]) by neon.ruby-lang.org (Postfix) with ESMTPS id D5DD31206AC for ; Wed, 29 Mar 2017 05:31:29 +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=y9nwR/z2WPDS5AGOVXAtOBGSQvQ=; b=YqjI/LwNwS/kPYvTKo 9I8QVXc6wy9QIAhXNzcLfIJZQNuWMGEgB07g95pHdQJl2VFp0XYAuW9GhuYbUx53 co+4ojI1TDrIH7PJwT6GTcXlPohcfNvgix1NwmnkczwuZI3NqOlaQ5kIv4/7b2fi 4jh/76hAOSYxiJpi//IVoN4lo= Received: by filter1090p1mdw1.sendgrid.net with SMTP id filter1090p1mdw1-18542-58DAC819-7F 2017-03-28 20:31:21.584828889 +0000 UTC Received: from herokuapp.com (ec2-54-158-236-224.compute-1.amazonaws.com [54.158.236.224]) by ismtpd0003p1iad1.sendgrid.net (SG) with ESMTP id Ck95F1QXQGqjo5ELd9CyXw Tue, 28 Mar 2017 20:31:21.549 +0000 (UTC) Date: Tue, 28 Mar 2017 20:31:21 +0000 From: burke@libbey.me To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 55408 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 13378 X-Redmine-Issue-Author: burke X-Redmine-Sender: burke 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/Ymy4QrNMhiuLXJG8OTL2vJD1yS4wdmWWFbe5IkMNHAd80r54rsPAZyy2iUvDFE iKbUnBsb+GRx+ZnTTWdK/2YnvgOGTaR+5gI6fT25+c1G36L9tN6JxNmx3dQNniWKkpLFUfNxpk+elS 6dgTXzLkCiZUfp3SxLO/Su63jJ75Rj89sNms X-ML-Name: ruby-core X-Mail-Count: 80438 Subject: [ruby-core:80438] [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 burke (Burke Libbey). File 0001-reduce-syscalls-on-require-fixed.patch added Ah, I was too hasty with the rebase from my 2.3.3 branch. I've attached a fixed patch. Note also that trunk has already eliminated the double-fstat, so this only reduces the number of syscalls when a feature is specified by absolute path (from 7 to 4). ---------------------------------------- Feature #13378: Eliminate 4 of 8 syscalls when requiring file by absolute path https://bugs.ruby-lang.org/issues/13378#change-63929 * Author: burke (Burke Libbey) * Status: Open * Priority: Normal * Assignee: * 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) -- https://bugs.ruby-lang.org/