proc t(): string =
var r {.global.} : string
r.setLen(0)
r.add("xx")
return r
proc main =
var a = t()
var b = t()
echo a
echo b
main()
From the naive split() use of the recent forum thread, I was wondering how one can save some allocations. The above example seems to work, and as strings and sequences have value semantics, it may work indeed for single threaded code? I would assume that it saves the allocation of the result variable -- for split proc it may save allocation of seq[string] as the result variable for each call?
I strongly assume that it will not work for multi-threaded code, but naive users may generally not use parallel processing.
I do generally not recommend Nim for naive users, there are many reasons like community size and available teaching material. And as long as naive Nim code is slower than Python, there is no much benefit for naive users with no CS background using Nim. And my observation is that these people generally are dissapointed by Nim and vanish soon.
Yes, you can use {.global.} for return values, but I'm not sure that you can save allocations, especially if a and b were to be modified after calling t(). I think there is some library that uses this pattern for caching purposes, but I don't quite remember.
As for the final paragraph, I'm not sure how that's related. Yes, there are a few naive examples where Python might outperform Nim that appear strange to those without a stronger CS background, but there are many naive code examples in other languages where the benchmarks have unintuitive results. But again, not everyone who tries Nim will be try to be rational and may end up dropping it like you said.
I just remembered that we have {.threadvar.} pragma, see
https://nim-lang.org/docs/manual.html#threads-threadvar-pragma
which may be better than {.global.}
Application should be code like
var myRes = split(longLine)[7]
I do generally not recommend Nim for naive users, there are many reasons like community size and available teaching material. And as long as naive Nim code is slower than Python, there is no much benefit for naive users with no CS background using Nim. And my observation is that these people generally are dissapointed by Nim and vanish soon.
Well growing the community by speading misinformation (Nim was faster than Python with -d:release, maybe read the thread completely...) about Nim is certainly a strategy that we haven't tried, thanks.
Well, spreading misinformation is bad, and I think I don't do it. But that unskilled naive users vanish fast seems to be a fact for me, and there must be reasons...
A Ferrari may be a good car, but for learning driving it may be not the best solution.
What really is sad is that many bright people with good CS education seems to have left Nim in the last 4 years since I am watching Nim -- I really hope some will come back eventually.
So effectively your reply is "Here is more misinformation".
Got any number to back up these claims? No? That's what I thought.
Yes, I was thinking the same some days ago. Now that we have -d:danger and -d:release it would make sense to make -d:release the default.
Araq may say users should just read tutorial and manual to learn about -d:release, and I would agree, but many people just do not do that. They copy and paste some Python code, try it, may be dissapointed and vanish. (In the past, before danger/release split, it was often the other way: People always compiled with -d:release from the beginning, and wondered about reasons for crashes.)
C and C++ don't compile with -O2 or -O3 by default.
Having -d:release be the default is bad because it means poor stacktraces and asserts don't work.
I think ease of debugging trumps performance for new people.
The proper way to deal with that is to have a FAQ and/or detailed articles/blog posts that explain what is going on.
We can even add an "info" hint after compiling that says. "Reminder: for full performance (non-debug) please use the -d:release flag and read on the -d:danger flag at nim-lang.org/building-nim-for-speed".
A cookbook that explains how to process strings would also be helpful.
Also I think we should invest in education, not just libraries (though a disclaimer at the beginning of strutils would help), the issue with slow string parsing is recurrent in all languages that don't use a GC and require the user to be aware that allocating memory in a loop is extremely slow.
A well-written article that explains that would also help more than the Nim community, similar to how many Linux distributions are using the Arch wiki as a reference for lots of low-level information.
While I agree with @mratsim basically across the board, to be fair to the proposal I think implicit was that there if the defaults switched there would be an easy way to activate debugging mode like nim c -d:debug. I think nim should be like all other compilers, though which is how it is currently.
I think the best course of action is just a new Hint that power users can turn off that tells newbies @mratsim's "Reminder". There could be two, even, one corresponding to d:release and one d:danger.
asserts don't work.
From what I read assert works well with -d:release?
For debug mode -- I am a bit tired of asking new users if they compiled in debug mode when they complain about performance. And much more important: When people try Nim only in debug mode and tell friends: Well I tried Nim for a trivial task, it is a bit faster than Python. That is no good advertising. Debug is less a problem, when people start to debug they have read some docs and know that it may be better to compile in debug mode.
I think the best course of action is just a new Hint that power users can turn off
Seems to be a very good solution.
I have come across a scenario where the gcc -O2/-O3 "over-optiimized" the code and that resulted in a buggy behavior.
So I needed to put a note to not pass the -d:release switch for that project. The discussion was on Nim IRC few months ago.
I have come across a scenario where the gcc -O2/-O3 "over-optiimized" the code and that resulted in a buggy behavior.
That is strange. For O3 the issue is known for a few C and C++ packages, as it it known that some packages do not work with -flto. But O2 should work always, and when there are problems with O3, Nim devs can fix it. But maybe O2 should be the default, O3 can make executables really large, without much speed gain.
I don't think it really argues/advises against @mratsim's warning/hint solution.
Correct.
The hint is fine. I was just saying that setting the default to -d:release would just switch to the other problem bucket.