From: eregontp@... Date: 2021-04-10T09:28:15+00:00 Subject: [ruby-core:103369] [Ruby master Feature#17790] Have a way to clear a String without resetting its capacity Issue #17790 has been updated by Eregon (Benoit Daloze). byroot (Jean Boussier) wrote in #note-6: > Maybe `String#capacity` and `String#capacity=` would make sense? But then there's the question of the behavior if you set the capacity to lower than the `size`. Should it truncate? (this could corrupt UTF-8 for instance) or should it raise? I would say definitely not truncate. So either raise an error, or do nothing, since the capacity is kind of a hint. My feeling is handling the capacity in Ruby code feels wrong and like C++ code. The example snippet above can just allocate a new String per call to `build_next_packet` and I doubt that would affect performance much: ```ruby 10.times do buffer = build_next_packet # build_next_packet can use String.new(capacity: 1024), it probably knows better about it anyway udp_socket.send(buffer) end ``` A bit more GC pressure, but I think anyway there would be many other allocations in `build_next_packet` that this wouldn't matter much. IMHO we should really have a separate Buffer class and String class here. For instance if the String class uses a rope representation (e.g. on TruffleRuby) a capacity doesn't make much sense. ---------------------------------------- Feature #17790: Have a way to clear a String without resetting its capacity https://bugs.ruby-lang.org/issues/17790#change-91462 * 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/ Unsubscribe: