[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] Fix wslib String *fill, or syncWithIDE?



Hi,

https://github.com/supercollider/supercollider/issues/980

It turns out that this issue is caused by a wslib extension, which overwrites the default String *fill method (inherited from Collection). Collection *fill pre-allocates 'size' slots and then uses .add to populate the new collection. This is efficient because .add will not have to return a new object (since the object is already big enough). String *fill in wslib uses ++, meaning that *every* iteration creates a new string and discards the previous one, placing a large load on the garbage collector.

I'm attaching a patch that avoids the problem by doing the same thing as Collection *fill inside ScIDEDocument syncFromIDE.

However, probably the better approach is if Wouter changes the name of his method to something like String.fillWithAnything. This may cause some static for wslib users, but the point has been made repeatedly about the dangers of overwriting core methods. It should never have been called *fill in the first place.

I'm not going to argue strenuously one way or the other, just noting that something needs to be done.

hjh
From fa2d28fcb218fc35addb40c30b731d4fc90235dd Mon Sep 17 00:00:00 2001
From: James Harkins <jamshark70@xxxxxxxxxxxxxxxxx>
Date: Mon, 21 Oct 2013 13:24:20 +0800
Subject: [PATCH] Classlib: ScIDEDocument: Avoid use of String:*fill b/c of
 wslib inefficiency

---
 SCClassLibrary/scide_scqt/ScIDE.sc |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/SCClassLibrary/scide_scqt/ScIDE.sc b/SCClassLibrary/scide_scqt/ScIDE.sc
index e79f9fa..ad1db4b 100644
--- a/SCClassLibrary/scide_scqt/ScIDE.sc
+++ b/SCClassLibrary/scide_scqt/ScIDE.sc
@@ -413,9 +413,11 @@ ScIDEDocument : Document {
 	}
 
 	*syncFromIDE {|quuid, title, chars, isEdited|
-		var doc;
+		var doc, argChars;
 		isEdited = isEdited.booleanValue;
-		chars = String.fill(chars.size, {|i| chars[i].asAscii});
+		argChars = chars;
+		chars = String(argChars.size);
+		argChars.do { |ch| chars.add(ch.asAscii) };
 		if((doc = this.findByQUuid(quuid)).isNil, {
 			doc = super.prBasicNew.initFromIDE(quuid, title, chars, isEdited);
 			allDocuments = allDocuments.add(doc);
-- 
1.7.9.5