The following is echo "Hello world" in js -d:release --opt:size. Is there anything that can be done about it?
/* Generated by the Nim Compiler v1.6.6 */
var framePtr = null;
var excHandler = 0;
var lastJSError = null;
function toJSStr(s_33556807) {
var Temporary5;
var Temporary7;
var result_33556808 = null;
var res_33556842 = newSeq_33556825((s_33556807).length);
var i_33556843 = 0;
var j_33556844 = 0;
Label1:
do {
Label2:
while (true) {
if (!(i_33556843 < (s_33556807).length)) break Label2;
var c_33556845 = s_33556807[i_33556843];
if ((c_33556845 < 128)) {
res_33556842[j_33556844] = String.fromCharCode(c_33556845);
i_33556843 += 1;
} else {
var helper_33556857 = newSeq_33556825(0);
Label3:
do {
Label4:
while (true) {
if (!true) break Label4;
var code_33556858 = c_33556845.toString(16);
if (
(((code_33556858) == null ? 0 : (code_33556858).length) ==
1)
) {
helper_33556857.push('%0');
} else {
helper_33556857.push('%');
}
helper_33556857.push(code_33556858);
i_33556843 += 1;
if (((s_33556807).length <= i_33556843)) Temporary5 = true;
else Temporary5 = s_33556807[i_33556843] < 128;
if (Temporary5) {
break Label3;
}
c_33556845 = s_33556807[i_33556843];
}
} while (false);
++excHandler;
Temporary7 = framePtr;
try {
res_33556842[j_33556844] = decodeURIComponent(
helper_33556857.join(''),
);
--excHandler;
} catch (EXCEPTION) {
var prevJSError = lastJSError;
lastJSError = EXCEPTION;
--excHandler;
framePtr = Temporary7;
res_33556842[j_33556844] = helper_33556857.join('');
lastJSError = prevJSError;
} finally {
framePtr = Temporary7;
}
}
j_33556844 += 1;
}
} while (false);
if (res_33556842.length < j_33556844) {
for (var i = res_33556842.length; i < j_33556844; ++i) {
res_33556842.push(null);
}
} else res_33556842.length = j_33556844;
result_33556808 = res_33556842.join('');
return result_33556808;
}
function rawEcho() {
var buf = '';
for (var i = 0; i < arguments.length; ++i) {
buf += toJSStr(arguments[i]);
}
console.log(buf);
}
function makeNimstrLit(c_33556801) {
var result = [];
for (var i = 0; i < c_33556801.length; ++i) {
result[i] = c_33556801.charCodeAt(i);
}
return result;
}
if (!Math.trunc) {
Math.trunc = function (v) {
v = +v;
if (!isFinite(v)) return v;
return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
};
}
function newSeq_33556825(len_33556827) {
var result_33556828 = [];
result_33556828 = new Array(len_33556827);
for (var i = 0; i < len_33556827; ++i) result_33556828[i] = null;
return result_33556828;
}
rawEcho(makeNimstrLit('Hello world!'));
This is normal, as Nim is a compiler, so it treats JS like a proper backend. You can try -d:danger for smaller code, --opt:size is a no-op for JS.
For bigger optimizations check out https://github.com/google/closure-compiler/, but it's really only useful if you can find externs for all the JS libraries you're using.
For example, after compiling the JS code with -d:danger and running:
closure-compiler --compilation_level ADVANCED_OPTIMIZATIONS --js tt.js --js_output_file ttopt.js
I get this:
var k=0;function l(g){var f=Array(g);for(var a=0;a<g;++a)f[a]=null;return f}for(var m=[],n=0;13>n;++n)m[n]="Hello, World!".charCodeAt(n);
(function(){for(var g="",f=0;f<arguments.length;++f){var a=arguments[f],c=l(a.length),d=0,e=0;b:for(;;){if(!(d<a.length))break b;var b=a[d];if(128>b)c[e]=String.fromCharCode(b),d+=1;else{var h=l(0);c:do for(;;){b=b.toString(16);1==(null==b?0:b.length)?h.push("%0"):h.push("%");h.push(b);d+=1;if(b=a.length<=d?!0:128>a[d])break c;b=a[d]}while(0);++k;try{c[e]=decodeURIComponent(h.join("")),--k}catch(p){--k,c[e]=h.join("")}finally{}}e+=1}if(c.length<e)for(a=c.length;a<e;++a)c.push(null);else c.length=
e;g+=c.join("")}console.log(g)})(m);
Huge thanks, @Yardanico, you are both knowledgeable and kind!
May I ask your personal opinion on using Nim for client-side DOM JS? I mostly do own performant vanilla with occasional small modules, e.g. Sortable, etc — and interested in expert opinions before diving in. Any caveats / gotchas that maybe come to your mind?
This console verbosity is the only quirk I've found so far — maybe there are other to be aware of?
Love Nim, but being new — just not sure if writing JS in is an actual viable option if performance and size are important — or it's all more of a dev experiment / proof of concept — super cool, but not for production.
import std/jsconsole
console.log "Helo, World"
compiled with nim js -d:release -d:nodejs jstest.nim results in
/* Generated by the Nim Compiler v1.6.6 */
var framePtr = null;
var excHandler = 0;
var lastJSError = null;
console.log("Helo, World");
It's not default because it's made specifically for native backends (C/C++/ObjC) and is used when you want your binary size to be as small as possible, sacrificing some performance in return.
With -d:release and -d:danger --opt:speed is used, which maximizes speed. But for things like embedded you might want to use --opt:size instead, that's why it exists.
And again, as I said, --opt doesn't affect the JS backend at all.
Yeah I'm a monster because I think that there are already enough incentives for saving energy. It costs money. No absurd exaggerations about the earth's immediate doom are required. No need for Sith rhetoric.
And I still have no responsibility whatsoever to do anything about these 500 bytes that could be optimized out. I will accept PRs though. But what if creating the pull request and me reviewing it takes up more energy than what we save by it? Will the climate be gentle and understand that it is was Co2 spent for the greater good of saving Co2 in the long run?
Hi :)
First things first -- @Araq has been generous enough to have a separate conversation with me, and we've agreed to disagree.
@tcheran: I had no intention of blaming or shaming, only pointing out that (a) download speeds are a major issue for millions of people, and (b) energy over-consumption fuels climate change, with data transfer being part of that. I did this to highlight that payload size has real-world implications, and is far from a "cult".
I also pointed out that this could be an issue resolved by the community if it was outside the Nim team's purview.
All reasonable, no?
As for the "jump" from download size to energy, larger payloads require more energy to store and deliver. That's physics! :)
He can be a bit harsh sometimes, his "brutally honest" approach is part of him.
Honest? Hmm. Unfortunately I prefer evidence-informed honesty rather than.... well, whatever form of 'honesty' has been expressed here.
He's probably more focused on PR as "Pull Requests" than as "Public Relations".
But he still found time for ad-hominem insults.
Ah well. Disappointing all round.
I notice that a couple of people thought the downstream JS tests would be a good idea. It would be nice to see those implemented, and I look forward to the community's contributions.
We're really talking about climate change and energy consumption in relation to the size of Nim's compiled JS?
You sure are finding the most ridiculous thing in the world to complain about re: energy consumption with this one... As someone who worked on helping Carfax's used cars website overtake cars.com, Car Gurus and Autotrader in Google search results, I agree with Araq that content and how it is crawled matters much more than a few KB in your JS.
I also agree that the WEF's agenda is much scarier than the kilobytes of data that Nim's compiler is contributing to "climate change".
Here is some honesty - if you really want to do something productive to help the environment, there are much more productive methods than this. Modifying your behaviors to be more climate-friendly, since you're convinced that humans are destroying the planet via energy consumption / greenhouse emissions (although we all laughed at Al Gore the first time this theory was proposed, and the earth goes through geological climate cycles naturally to begin with) would be a much better place to start, as you actually have control over those things.
I've been putting off this thread because it got weird and I couldn't follow but it seems to have calmed down.
It's good to be wary that Nim does not explode its JS output size. However it is unfair to say that Nim is overly lenient with regard to the JS output size and Nim users will have the rug pulled from under them for using the JS backend.
This is especially true when you consider other languages that compile to JS or even JS frameworks that emulate what Nim can do with metaprogramming or just normal language features. Nim in fact generally beats its competitors in this regard.
It may be that compared to the alternatives, Nim produces more mechanical and unreadable JS code. However sometimes this is actually faster because of JS being weird or engine specific quirks or whatever. Bigger code size doesn't necessarily imply that engines will use more CPU/memory either. I can't really give an informed account here because it's difficult to benchmark such a general issue but I doubt there's many issues to encounter. If people notice something is wrong and investigate, as said above it's fine to deal with it, but specifically searching for issues isn't worth the time and effort.
If you are concerned about bandwidth use, minifying Nim JS output usually brings the size down by 50% (mostly because of whitespace), and gzip brings it down to basically nothing (20 kb max if you are careful). Compared to other files on most webpages Nim really doesn't have any impact.
We should really have FAQ answers or wiki pages or whatever for stuff like this.