I am considering using ChaiScript in several projects. First I should say that it’s a very interesting library.
Is there any way to serialize and deserialize the state of a chaiscript vm? For example to generate save states. I could have the whole state outside the scripts (in the C++ part only) but then it would make more difficult to write scripts as script-local values would not be saved/loaded.
I was looking at the engine header and remarked heavy use of std::map and std::set. Did you consider replacing them by sorted vectors? I mean exactly like boost::container::flat_set and flat_map (but maybe your own implementation to not require boost). I believe (but didn’t try yet) that it could help with performance.
No we don’t have any built in way to serialize the state of the VM. I’m not entirely sure if it would be possible to implement it in a reasonable way. We might be able to save the currently defined ChaiScript functions, but variables are C++ objects which may or may not be opaque to the engine.
What exactly (local variables / C++ functions / ChaiScript functions / type conversions) would you need to serialize for it to be useful? Would you need the serialization to be portable across platforms?
You might be interested in the get/set state functions. They don’t give any way to serialize, but do let you at least set and restore the state within one execution.
I’m getting ready to spend some time on that kind of thing in the next few days, as soon as I get the chance. The actual lookup times of map/set elements haven’t turned up very much on profiles yet, there have been bigger fish to fry so far.
If you have some code, please submit it.
Thanks. And thank you for your support on Stack Overflow in the past.
To be clear about my need: I would like to be able to just stop executing code through the vm,
then store somewhere the state of the vm so that I can reload it later.
This mean that the whole execution context have, indeed, to be kept in the serialized form.
I already know that I can have the scripts store “to be saved” values in my own objects exposed to the scripts, but I would like to simplify this process if possible, so that nothing special have to be done on the script side if it wants to build up script-local data.
Of course this is a major “it would be very useful but it’s ok without it for now” kind of feature.
From the current code (I just looked quickly at it) it seems possible but maybe it’s tricky if the c++ code is modified or if it needs to be cross-platform.
Ideally yes. Actually, in my current game I wouldn’t use such feature if it didn’t work across platforms.
I believe it should be doable as long as we don’t necessarily need a compressed or crypted serialized format, utf-8 text would be enough and the user code can still crypt/compress if he wants.
Yes it’s enough for now, though the feature I suggest would be a major next-step over this.
I don’t have a complete detailed understanding of ChaiScript because I didn’t use it in a big project yet but want to do that soon, so any help with this point is useful at least to me.
I don’t have much time these days unfortunately (I must go forward with that game…) but I will submit something if I end up finding time, I can’t just promise anything right now.
I believe for this particular point, if Boost was a required dependency, I would just replaced any set or map usage by boost’s flat_map/set, they have the same interface. I believe that it’s not hard to reproduce a simple equivalent though, they are just sorted vectors.
Haha don’t, ChaiScript looks very promising to me, so I point to it as much as I can (among other things though)
By the way, the Chimera author (working at Sony) asked on twitter for such a script language and I pointed to ChaiScript. It looked very promising to him, the only issue was lack of feedback from actual commercial projects having used ChaiScript. Do you have any such feedback? We couldn’t find any online.
I continued to think about the serialization problem but I have too much unrelated work to try something immediately so I’ll ask here first:
It seems to me that if the user provide serializable objects (for example, that implement << and >> operators with std::o/istream or something similar to Boost.Serialization) AND there is serialization functions provided that are guaranteed to work only work between eval calls and take a de/serializer and a chaiscript as argumen… then I see no problem implementing this.
Am I correct or am I missing something?
If I am correct and there is no major issues with this idea, as soon as I can find the time I would like to try this. It would let the ChaiScript user the choice of the way it will serialize things.
Maybe just a visitor function that allow going through all the loaded objects/functions/symbols would be enough for people to implement whatever they want, serialization included?
(I’m also tempted to help with “obvious” performance improvements but I lack time right now - I if I manage to find time I’ll make a pull request, I’ll just need to see your performance tests to check that my assumptions as correct)
How will you serialize C++ functions that have been exposed to ChaiScript? That will be virtually impossible, and undesirable also.
If you want to serialize just objects, that gets to be a little easier but you still have to deal with aliased objects:
var x = 4;
var y := x; // y is now an alias of x
The visitor pattern does seem like a potentially good idea. If you allow the user to specify the objects they want to serialize and/or the specific mechanism, then you could create an automatically walking serialization function.
Another possibility would be to only support primitives. So you could write out the state of all numerical, array, string types that currently exist as JSON or YAML or something similar.
If you happen to find any obvious improvements, have at them. The release I’m making today (5.5.1) is 30% faster again. I would like to think all of the obvious improvements have been taken. Lately I’m focusing on simplifying the code and helping the compiler’s optimizer do its job, and that has gone a long way.
Do you have a test suite somewhere that you use to measure performance changes? Or how did you proceed to measure the last performance improvements? I would like to try some things see if it actually helps before giving more suggestions.
I run it a few times and take the shortest time. Alternatives include running the same statement through valgrind and looking at the raw number of logged cpu cycles.
Also, these tests have been the same for a very long time, and the code is pretty well optimized for them. What might be more helpful would be to come up with something different that you see should be optimized and give me a pull request for it, to add to these tests.
Would it be ok to add a small program doing this in a cross-platform way? I can do this once I get back to trying things with ChaiScript.
So far I have issues running anything, there always seems to be exceptions thrown but I might be launching the tests incorrectly (I didn’t have time to dive further). Am I correct that launching the tests from a visual studio solution is not the way you do it? Maybe some arguments are missing in my case.
You can run it from VS directly, but it’s probably going to have a hard time finding the stdlib.
To get the CTest tests to run, I have to set the system environment variable so that chai.exe can find the chaiscript standard library dll:
If you want to make a tool that uses C++11’s chrono code to get more accurate timing results and calls these tests, go ahead. Put it down in the contrib folder, I think might be best. It might make sense to compile in the stdlib statically as well, to make it more self contained.