ID:2382252
 
BYOND Version:512.1435
Operating System:Linux
Web Browser:Chrome 67.0.3396.87
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary:
String concatenations that assign their result to an operand of the concatenation are significantly slower than those that do not

i.e.:
result = a; result += b
and
result = a; result = "[result][b]"
are significantly slower (~50% slower for 2-character strings, 13x slower for 400-character strings) than:
result = a + b
and
result = "[a][b]"


Numbered Steps to Reproduce Problem:
- Write two string concatenations concatenating long strings; one result = s1 + s2, and one result = s1; result += s2, where s1 and s2 are relatively long (~200+ character) strings.
- Execute both
- Observe that result = s1; result += s2 is approximately 50% slower for very small strings, 6x slower for 128-char strings, and 13x slower for 400-char strings.

Code Snippet (if applicable) to Reproduce Problem:
/world/loop_checks = 0
#define BENCHTK(NAME, ITERS, CODE) do{ var/s = world.tick_usage; for(var/j = 1 to 1000) { for(var/i = 1 to (ITERS)) { CODE ; } ; } ; var/e = world.tick_usage; world.log << "[NAME]:[(e-s) * world.tick_lag] ms"; } while(0)

// 400 chars each. The strings are just random data base64'd.
var/s1 = "oRmfshgsduoMKt8gsN0GybDdINIc0dpBJPHt9Vw9VoBabSXyPIs+JdUcyINr8fqpjAeR9tzbeYaozMwSC7VyppWMEozQCGNF53anE1+SfmNh7GnaeykB71atgYxtQv7lwlxjaLNAbjxP5fzhGIowVn5ZFNrigejPQ4o1yc1A7pjGCgRvo0cQKYQqcXOGLoZNfouWIogmZq7rblh8eENG/yjPE+Z7GL31h4fqzjm+KmwOs5esvT/N6vP+wCK2jM+6d3MvnmLMLZfDPaPwpxQJC0XnpAuEL26mnDqgQ9DSp8FellF/wgFdMakRiUuzSovfO6hQkkF8IZOrzvWttIql/jXjEApu0Rvr/RyPWGFtqrLJqsSAgil5QZ3yacd+pNzYVmERk+BQza+S+aXP"
var/s2 = "owfqYceSPQtxG+43xKoEY3qw9+QT20qhQhTV9A96Q7e4h4oI0CkUurrdMi4xcchjZzObFb4WD+wUmm8+Sf+R1K56Kh6ip72M/P/oi9cPSx7gNUJ5QSKwi8rvgvR3jETVPfo/vrWLuSeNWHGU6BNZwuSa7zbt/Of93bqUYPlSp4kSLWFhcoftj7jE9vYGRY9xUhaiwHBonVAh9CujM3MHqfJPsKc55j4n6zbbr+RVEAqaZM8kiVBXHl0V2Y1SS5ZXmyiOCoiE6kgVqBVJMNxxbnJJo02tIWgUDq+EsB0nlQ8Rpiy4MqX+ermXfrQib8UsXrJtfmc09wQcRwQgzTZ+0HCQD1F8jRA5NZLTwsD/io5tFd8/53crL3uyF7VlrINcw/n/GQR2IB4TtP0o"

/world/New()
BENCHTK("plus1", 5000, r = s1 + s2) // Straight concat. 1.68s
BENCHTK("embed1", 5000, r = "[s1][s2]") // Embedded strings. 1.90s
BENCHTK("join1", 5000, r = jointext(list(s1,s2),null)) // jointext. 3.84s
BENCHTK("plusM", 5000, r = s1; r += s2) // Straight concat, in-place. 22.5s (13.4x)
BENCHTK("embedM", 5000, r = s1; r = "[r][s2]") // Embedded strings, in-place. 24.4s (12.8x)
BENCHTK("joinM", 5000, r = list(s1); r += s2; r = jointext(r,null)) // jointext, in-place. 27.0s (7.0x)


Expected Results:
r = s1 + s2 and r = s1; r += s2 to be approximately equivalent
r = "[s1][s2]" and r = s1; r = "[r][s2]" to be approximately equivalent

Actual Results:






128-char 400-char
r = s1 + s2 1346ms 1683ms
r = s1; r += s2 8247ms 22498ms
r = "[s1][s2]" 1565ms 1901ms
r = s1; r = "[r][s2]" 9348ms 24417ms


Additionally, r = s1; r = r + s2 is approximately 2.5x slower than r = s1; r += s2.

Does the problem occur:
Every time? Or how often? Every time
In other games? Yes
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur? When you don't put the resulting string into the variable you're concatenating from.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked?

Workarounds: Don't reuse a variable to hold the result of your string concatenation?