tags:

views:

758

answers:

9

I currently use QtScript for scripting functionality in my C++ application, but it's rather "heavy" on the cpu. When a thread evaluates all the scripts in a loop the cpu usage increases to 90%-100%. Even when i put it to sleep for 1 msec every 5 scripts it stays above 75% cpu usage.

Are there any other, easy to implement, scripting frameworks which are much more lighter than QScript?

edit:

I now realize this is normal behavior and not some hogging bug in QtScript. Still it's interesting to hear what kinds of (lighweight) scripting libraries are available.

+16  A: 

Have a look at Lua, it's frequently used in games so the performance must be pretty good.

Adrian Grigore
Ah yeah, I heard of Lua before. I'll run some tests tomorrow.
corné
Won't executing a Lua script that doesn't block use 100% CPU? I would hope so, otherwise I'd consider it broken.
KeyserSoze
I guess it would, but he asked about a fast scripting library, so I made a recommendation.
Adrian Grigore
+3  A: 

Lua is good because it uses a stack to communicate between interpreter and C++. This is good, because it doesn't involve any reference counting visible to you which simplifies things.

Here is an interesting comparsion as a background for some iolanguage: iolanguage.

+12  A: 

Well, what do you expect? Unless the script has to wait for disk or user I/O, the CPU should run at 100%.

Is your problem that it runs to long?

Or that your application is unresponsive?

In that case, the problem is that your script is blocking the thread where all the UI interactions run. The general solution is to block all UI input (except the "cancel script" button :)), and move the actual processing to a separate thread.

[edit]
Slightly different question: is the CPU at 100% while there is no script to process?

100% CPU is good and healthy, if you are processing something.

The CPU is always busy, the current thread always consumes 100% of the core it is running on. "0% CPU activity" actually means all cycles are spent in an system idle thread (that belongs to the "system idle process" you see in task manager).

As an simplistic example: if you have one application thread active, and CPU usage is 40%, and your task manager update interval is 1s, 400ms of CPU time was spent on the application, and 600ms on the idle thread.

peterchen
No it's not blocking anything or running slow. I have a lot of threads and 1 of them processes qscripts. Most of the threads are using around 1-2% cpu, but the qscript thread around 90%. Of course the scripts should run fast, but it should not heavily load the cpu. Maybe i'm wrong about this, but most application don't use 100% cpu, not even when they're busy. This shouldn't be different with scripts right?
corné
Depending on how the operating system handles things, it's quite possible to see threads run 90%-100% CPU utilization for extended periods of time, especially if no other process is needing CPU time. If you truly want to limit this, trying playing around with the priority you have for the thread running the scripts.
Caleb Huitt - cjhuitt
Agreed with parent, 100% CPU usage is correct (and desirable) behavior. You are giving the CPU a long list of things to do (the script), why the fuck would you expect it to sit around on it's ass instead of doing what you told it to do (ie: execute the script)?
KeyserSoze
I guess you're right about this and I realize I should learn more about threading. But because this is not a real answer to my question, I'll upvote you instead :)
corné
it's ok, I'll get over it ;) good that you updated your question, too, as to not shed bad light on QScript.
peterchen
+2  A: 

I've heard good things about TinyScheme. That having been said, we're using Lua here (at a game development studio, targeting embedded and hand-held systems).

Things to note, though -- with Lua specifically, but I think these apply to many of these languages:

  • A custom lightweight small object allocator can gain a lot of performance; many of these lanugages are alloc-heavy. Using pooling or a frame-based allocator may be worth your while, depending on what you can get away with.
  • Depending on the GC strategy used (since most of these languages are garbage collected) you'll want to keep the GC scan area small -- e.g. a small lua heap size overall. Spending some time reorganizing data to get it outside of the domain of the GC (e.g. keeping it C++ side, tagging it somehow so the GC knows to avoid it, etc) can help.
  • Similarly, incremental garbage collection can be a big win. I'd recommend experimenting -- in some cases (small heap) I've found full GC faster than incremental.
leander
+2  A: 

I personally would recommend Lua having used it extensively in our embedded platform. If you are running on windows, you might be able to use something like LuaJIT to make your Lua even faster

However, since no one has mentioned it, you might also want to take a look at Squirrel (http://squirrel-lang.org/). I haven't had any experience with it, but I think it looks promising.

As to your currently problem, any code will take 100% of the CPU if it doesn't have anything that will block it.

something like (pseudocode):

for(i=1,10000000000000) n=n+i end

will take 100% of the CPU until it completes in (almost) any language because there is nothing to stop it from executing.

Dolphin
+1  A: 

It really depends on several factors:

  • Will scripting be used a lot in your application?
  • Will the scripts be complex?
  • Are you exposing a lot of functionality to the script engine?
  • Do you care for a good integration into Qt?

I also recommend Lua, however, you should keep the following in mind: Lua is implemented in pure ANSI C. This makes it uber-portable, but if you're developing in a C++ environment, it will lead to a lot of "wrapping" classes. Especially when you would like to expose Qt functionality (with all it's SIGNALs, SLOTs, and PROPERTYs), it leads to a lot of duplicate code.

beef2k
Please never write Lua as all-caps. http://www.lua.org/about.html#name
Alexander Gladysh
There is not need to wrap anything, though you may choose to. The standard Lua distribution compiles just fine as C++.I use Lua in a mixed C/C++ environment, so we use it without wrappers. It is kind of annoying (to a C++ programmer) to have to pass a lua_State* to every function in the C world, but it is entirely doable, and not that big of a deal.
Dolphin
Yes, it is doable. But my point was that all the good features of C++ - especially in combination with Qt - may lead to a lot of wrapping. Within the script, you would like to call methods of the host application, so they need to be exposed. Because Lua does not support C++ functors, it could be tedious to implement this.
beef2k
+1  A: 

Lua is your language of choice. There are some bindings for Qt.

Alexander Gladysh
A: 

You can also embedd javascript with spidermonkey I think javascript is more widespread than lua.

piotr
A: 

Nothing wrong with QtScript from what I can tell so far (only started using it from 4.6 so still new to it, but liking it so far). Depends on how you use it, just like lua or python. If you keep as much of your application's core functionality native (compiled from c/c++) and only expose a minimal API to the script engine then, in general, you can keep things snappy.

With QtScript it is relatively easy to expose objects and their methods in a reasonably thread-safe manner (QT's slots and signals object model) and easily pass script created objects to native functions... but you can end up being tightly integrated with the QT environment (Which might be exactly what you want sometimes).

If you want to arbitrarily expose native c++ objects to other embedded scripting environments checkout SWIG. SWIG is similar to the toLua tool, but works for many embeddable languages like lua, c#, tcl, java and python to name a few. From experience, toLua made binding objects and methods to scripts a much less painful process, and I haven't heard many bad things about SWIG either.

JQ