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=-2.7 required=3.0 tests=AWL,BAYES_00, DKIM_ADSP_CUSTOM_MED,FORGED_GMAIL_RCVD,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY shortcircuit=no autolearn=no 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 EE8EC1F4B4 for ; Sat, 10 Apr 2021 15:18:01 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id E8860120D6D; Sun, 11 Apr 2021 00:16:56 +0900 (JST) Received: from xtrwkhkc.outbound-mail.sendgrid.net (xtrwkhkc.outbound-mail.sendgrid.net [167.89.16.28]) by neon.ruby-lang.org (Postfix) with ESMTPS id 7C365120993 for ; Sun, 11 Apr 2021 00:16:55 +0900 (JST) Received: by filterdrecv-59db977c98-wfzwk with SMTP id filterdrecv-59db977c98-wfzwk-14-6071C19C-3E 2021-04-10 15:17:48.735489298 +0000 UTC m=+1376025.663014198 Received: from herokuapp.com (unknown) by geopod-ismtpd-3-1 (SG) with ESMTP id kjbpbKAfRUWM1IJ5oC1Reg for ; Sat, 10 Apr 2021 15:17:48.577 +0000 (UTC) Date: Sat, 10 Apr 2021 15:17:48 +0000 (UTC) From: jean.boussier@gmail.com Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 79420 X-Redmine-Project: ruby-master X-Redmine-Issue-Tracker: Feature X-Redmine-Issue-Id: 17790 X-Redmine-Issue-Author: byroot X-Redmine-Sender: byroot 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: =?us-ascii?Q?AchqQMoUBMcQgz7gop0XiYUiatGIY7E61JGsTL4Fvjd12V=2FnJ1IU+H9Vn2oS3W?= =?us-ascii?Q?gNb3BQXHLfTkkSb1rGHJHHapcarwfbgTfatHe25?= =?us-ascii?Q?Hpp+EkovK+o=2Fp98G0ZcqECbNk5z6qGAJ09hxtQu?= =?us-ascii?Q?YvjSHw6AAQauEzen4zvDZ892rp5QGf=2FMLAlmjd7?= =?us-ascii?Q?QbY9ZsLxk8vgtJ2DquJ1+5lodTuu3AgIulI0RfF?= =?us-ascii?Q?CpfqPk5S3bM0k+izI=3D?= To: ruby-core@ruby-lang.org X-Entity-ID: b/2+PoftWZ6GuOu3b0IycA== X-ML-Name: ruby-core X-Mail-Count: 103373 Subject: [ruby-core:103373] [Ruby master Feature#17790] Have a way to clear a String without resetting its capacity 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 #17790 has been updated by byroot (Jean Boussier). > My feeling is handling the capacity in Ruby code feels wrong and like C++ code. This is really meant for the few low level places where it matters. For context this came up when trying to optimize a StatsD client, which is quite a hotspot. More generally there are cases when you know you'll return a large String/Array/Hash, and you know the size in advance, and it can make sense to pre-reserve capacity rather than having it resized a dozen times. Amusingly enough the C API allow to create an array or hash with a specific capacity. > IMHO we should really have a separate Buffer class and String class here. Possibly yes. StringIO is kind of meant to be that buffer class, but it's not always easier to use, and often is slower than using a string. > I think clear(shrink: true/false) would be fine to add. I think it would be good, but would also require a `String#resize(capacity)` as well. So the pattern would be: ``` buffer = String.new(encoding: Encoding::BINARY, capacity: 1024) loop do # do your thing buffer.clear(shrink: false) buffer.resize(1024) end ``` ---------------------------------------- Feature #17790: Have a way to clear a String without resetting its capacity https://bugs.ruby-lang.org/issues/17790#change-91466 * Author: byroot (Jean Boussier) * Status: Open * Priority: Normal ---------------------------------------- In some tight loop it can be useful to re-use a buffer string. For instance: ```ruby buffer = String.new(encoding: Encoding::BINARY, capacity: 1024) 10.times do build_next_packet(buffer) udp_socket.send(buffer) buffer.clear end ``` Currently `Array#clear` preserve the Array capacity, but `String#clear` doesn't: ```ruby >> puts ObjectSpace.dump(Array.new(20).clear) {"address":"0x7fd3260a1558", "type":"ARRAY", "class":"0x7fd3230972e0", "length":0, "memsize":200, "flags":{"wb_protected":true}} >> puts ObjectSpace.dump(String.new(encoding: Encoding::BINARY, capacity: 1024).clear) {"address":"0x7fd322a8a320", "type":"STRING", "class":"0x7fd3230b75b8", "embedded":true, "bytesize":0, "value":"", "memsize":40, "flags":{"wb_protected":true}} ``` It would be useful if `String#clear` wouldn't free allocated memory, but if it's a backward compatibility concern to change it, then maybe another method could make sense? -- https://bugs.ruby-lang.org/