Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate:

Account: (login)

More Channels


Showcase


Channel Catalog


Channel Description:

ClearScript is a library that makes it easy to add scripting to your .NET applications. It currently supports JavaScript (via V8 and JScript) and VBScript.

older | 1 | .... | 14 | 15 | (Page 16) | 17 | 18 | .... | 115 | newer

    0 0

    That's great news. I was beginning to think there may be a problem with my system or I was going crazy.

    Any time
    frame on getting the fix sent out?

    0 0
  • 01/05/14--19:46: New Post: Strong Name
  • If you don't release official binaries, who's responsible for the ClearScript packages on NuGet?

    0 0
  • 01/06/14--05:26: New Post: Strong Name
  • All NuGet packages are provided and maintained by their owners. Please see the package page for owner information.

    0 0

    We're currently on track to post the ClearScript 5.3.11 source code later this week.

    0 0
  • 01/06/14--07:36: New Post: Benchmarks
  • What is GlobalMembers support?

    When I ran the test below, I only see a small performance increase after disabling global members. Also, I compared it with Javascript.NET and the differences is huge. But if I compiled the script before running it, it is almost 2~3X of Javascript.NET. (Our application needs to update hundreds if not thousands of items when a property is modified, so measuring performance like this is very important)

    Script is "Math.random();"

    Clearscript in 942
    Clearscript with DisableGlobalMembers in 930
    Javascript.NET in 21

    //After compiled
    Clearscript in 57
    Clearscript with DisableGlobalMembers in 53
    Javascript.NET in 27
    public static void TestClear(string script, bool disableGlobal)
    {
        var engine = new V8ScriptEngine(disableGlobal ? V8ScriptEngineFlags.DisableGlobalMembers : V8ScriptEngineFlags.None);
        
        var sw = new Stopwatch();
        sw.Start();
    
        //var compiled = engine.Compile(script);
    
        for (int i = 0; i < 10000; i++)
        {
            //engine.Evaluate(compiled);
            engine.Evaluate(script);
        }
    
        sw.Stop();
        Console.WriteLine("Clearscript" + (disableGlobal ? " with DisableGlobalMembers" : "") + " in " + sw.ElapsedMilliseconds);
    }

    0 0
  • 01/06/14--09:41: New Post: Benchmarks
  • I notice the bottleneck is here
    var uniqueName = documentNameManager.GetUniqueName(documentName, "Script Document");
    It is generating a new name even the same script is being executed twice. If I changed it to
    uniqueName = code.GetHashCode().ToString() // Just an example to create a unique code based on the script
    If the same script is being executed twice, it will run extremely fast and efficient (Should have the same performance as compiling the script).

    I think Javascript.NET has similar optimization because the first code below runs almost 8~10x slower than the second one
    for (int i = 0; i < 10000; i++)
    {
          engine.Run("Math.random() + " + i);
    }
    
    for (int i = 0; i < 10000; i++)
    {
          engine.Run("Math.random()");
    }
    

    0 0
  • 01/06/14--09:49: New Post: Benchmarks
  • Hi ravetam!

    GlobalMembers is an old Windows script engine feature that we added to V8ScriptEngine for API compatibility. It allows you to expose a host object so that its members (rather than the object itself) appear as global properties within the script environment. Support for this feature is expensive on V8 even when it remains unused, so the only way to avoid the performance hit is to disable it completely.

    Now, as for your performance numbers...

    V8 executes "Math.random()" extremely quickly; if you move the loop into script code, you'll see that it can run 10,000 iterations in just a couple of milliseconds. In fact, compiling such a script probably makes little or no difference in terms of execution speed. What you're really measuring there is the overhead of invoking V8 via ClearScript vs. JavaScript.NET.

    We took a look and were surprised to find that generating a unique script name represents most of ClearScript's overhead. When you compile the script you do this once as opposed to 10,000 times, and that explains the improvement over raw script execution. We'll definitely take a closer look at this.

    The remaining difference - approximately twice the invocation overhead for ClearScript vs. JavaScript.NET - is likely due to differences in library design. JavaScript.NET is definitely lighter, and its single-assembly design is an advantage.

    Thanks for bringing this to our attention!

    0 0
  • 01/07/14--06:54: New Post: Benchmarks
  • Thanks for the explanation on GlobalMembers.

    I just realize that the script still works even no unique name is generated (Using a same document name). Is there any pitfall or anything that I should be aware of if i plan on using that?

    0 0
  • 01/07/14--07:26: New Post: Benchmarks
  • Heh, it looks like we were investigating simultaneously :)

    It is generating a new name even the same script is being executed twice.

    Right. When you call a method that takes the code as a string, ClearScript considers it a new script. It doesn't cache the code for subsequent lookup, deferring to the underlying script engine for that sort of optimization. It might benefit from doing what you suggest, but the code cache could also explode under some usage patterns.

    By the way, the unique script name is just metadata that shows up in script debuggers; it doesn't affect script execution. JavaScript.NET doesn't bother with script names at all, probably because it doesn't support script debugging.

    If the same script is being executed twice, it will run extremely fast and efficient (Should have the same performance as compiling the script).

    If that's how it works, then V8 does it all under the covers. Neither ClearScript nor JavaScript.NET look up previously compiled scripts. When given a code string to execute, they both call V8's compilation method and then its execution method.

    I think Javascript.NET has similar optimization because the first code below runs almost 8~10x slower than the second one

    It's possible that V8 does what you suggest behind the scenes, but it could also be that V8 optimizes "Math.random()" completely away when it detects that your script doesn't use the return value.

    Cheers!

    0 0
  • 01/07/14--07:32: New Post: Benchmarks
  • I just realize that the script still works even no unique name is generated (Using a same document name). Is there any pitfall or anything that I should be aware of if i plan on using that?

    Only that you might confuse script debuggers. Come to think of it, we've never tested debugging support without unique script names.

    0 0
  • 01/07/14--07:41: New Post: Benchmarks
  • Heh, it looks like we were investigating simultaneously :)
    Yeah, love the extension method and ability to add host type (enum, static class) in Clearscript. Just trying to make it work.
    Only that you might confuse script debuggers. Come to think of it, we've never tested debugging support without unique script names.
    Good point but maybe you can consider only turning on unique script name generation when this flag is present? V8ScriptEngineFlags.EnableDebugging

    0 0
  • 01/08/14--05:46: New Post: Benchmarks
  • Good point but maybe you can consider only turning on unique script name generation when this flag is present? V8ScriptEngineFlags.EnableDebugging

    We'd prefer to keep the unique names for now, as they also show up in script error stack traces, which V8 makes available even when debugging is disabled. With some improvements we're making in the next release, generating a unique name takes approximately 600 nanoseconds on an old Core i7 920 PC; this is unlikely to affect real-world script execution times significantly. Besides, if you're executing a script many times, you can compile it to eliminate the overhead.

    0 0

    I'm trying to create a command-prompt with a functionality like the console.log in my engine.
        public class Konsoll
        {
            public void log(dynamic o)
            {
                Console.WriteLine("Type:" + o.GetType());
                Console.WriteLine(o.ToString());
                // var p = (Microsoft.ClearScript.V8.V8ScriptItem)o;
    
                // foreach (o.GetType().)
            }
    
        }
    used like this
                using (var engine = new V8ScriptEngine())
                {
    
                    engine.AddHostObject("console", new Konsoll());
                    string str;
                    while ((str = Console.ReadLine()) != "end")
                    {
                        engine.Execute(str);
                    }
                }
                Console.ReadLine();
            }
    How would you recommend to do this? It would be a very nice start if you made V8ScriptItem public. Maybe this object should rather be of type ExpandoObject?

    0 0

    I found a solution. The V8ScriptItem is a DynamicObject - so this works:
        public class Konsoll
        {
            private void logg(int indent, dynamic o)
            {
                foreach (string egenskap in o.GetDynamicMemberNames())
                {
                    Console.Write(new String(' ', indent));
                    Console.Write(egenskap);
                    Console.Write(':');
                    
                    if (o[egenskap] is System.Dynamic.DynamicObject)
                    {
                        Console.WriteLine();
                        logg(indent + 1, o[egenskap]);
                    }
                    else
                    {
                        Console.WriteLine(o[egenskap].ToString());
                    }
                }
            }
            public void log(dynamic o)
            {
                logg(0, o);
            }
    
        }
    so
    engine.Execute("console.log({v1:4,v2:['a','bc', 'de', {f:'g'}],h:1,i:2,j:3,k:4});");
    will output
    v1:4
    v2:
     0:a
     1:bc
     2:de
     3:
      f:g
    h:1
    i:2
    j:3
    k:4
    Clearscript is really cool stuff.

    0 0

    Glad that you found a solution!

    V8ScriptItem is just a concrete implementation of DynamicObject. It doesn't have any additional members that would be useful to the host. The idea is that you either use its DynamicObject members, or you use it via the dynamic keyword.

    By the way, it would probably be best to minimize your use of the dynamic machinery. Declaring a variable as dynamic causes the compiler to emit a dynamic callsite everywhere that variable is used, and that could get very expensive, especially when combined with the overhead of invoking V8. Consider rewriting your class something like this:
    publicclass Konsoll {
        privatevoid logg(int indent, DynamicObject od) {
            foreach (string egenskap in od.GetDynamicMemberNames()) {
                Console.Write(new String(' ', indent) + egenskap + ':');
                object m = ((dynamic)od)[egenskap]; // this is the only dynamic callsitevar md = m as DynamicObject;
                if (md != null) {
                    Console.WriteLine();
                    logg(indent + 1, md);
                }
                else {
                    Console.WriteLine(m);
                }
            }
        }
        publicvoid log(DynamicObject od) {
            logg(0, od);
        }
    }
    Another option might be to expose only System.Console and implement console entirely in script code.

    Good luck!

    0 0

    Hi again!

    ClearScript 5.3.11 will support JScript 5.8 language enhancements, including the JSON object, but you'll have to enable them explicitly via a new flag. That's because these enhancements come with their own bugs and backward compatibility issues - part of the reason why websites back in the IE8 days had to opt-in to "Standards Mode" :)

    Cheers!

    0 0

    Thanks for the warning. I wanted to know just how expensive the dynamic statement was - so I ran a test. The Console.Write was 3-4 times as fast, but to be fair, I added a third way "console.logs" deserializes a JavaScript literal and uses the same recursive printing style as console.log.
    public class Konsoll
        {
            public int Indent = 0;
            public JavaScriptSerializer jss = new JavaScriptSerializer();
            public void logs(string s)
            {
                object o = jss.DeserializeObject(s);
                loggs(0, o);
            }
            private void loggs(int indent, object o)
            {
                if (o is Dictionary<string, object>)
                {
                    foreach (KeyValuePair<string, object> kvp in (Dictionary<string, object>)o )
                    {
                        Console.Write(kvp.Key);
                        Console.Write(':');
                        loggs(indent + Indent, kvp.Value);
                    }
                }
                else if (o is Object[])
                {
                    for (int i = 0; i < ((Object[])o).Length; i++)
                    {
                        Console.Write(i);
                        Console.Write(':');
                        loggs(indent + Indent, ((Object[])o)[i]);
                    }
                }
                else if (o == null)
                {
                    Console.Write("null");
                }
                else
                {
                    Console.Write(o.ToString());
                }
    
            }
            private void logg(int indent, object o)
            {
                
                if (o is System.Dynamic.DynamicObject)
                { 
                    
                    foreach (string egenskap in ((System.Dynamic.DynamicObject)o).GetDynamicMemberNames())
                    {
                        // Console.Write(new String(' ', indent));
                        Console.Write(egenskap);
                        Console.Write(':');
                        logg(indent + Indent, ((dynamic)o)[egenskap]);
                    }
                }
                else if (o == null)
                {
                    Console.Write("null");
                }
                else
                {
                    Console.Write(o.ToString());
                }
            }
            public void log(object o)
            {
                logg(0, o);
            }
    
        }
    Writing a test:
                using (var engine = new V8ScriptEngine())
                {
                    engine.AddHostObject("console", new Konsoll());
                    engine.AddHostType("Console", typeof(System.Console));
                    var start3 = DateTime.Now;
                    for (int i = 0; i < 1000; i++)
                    {
                        engine.Execute("Console.Write(JSON.stringify({v1:4,v2:['a','bc', 'de', {f:'g'}],h:1,i:2,j:3,k:4}));");
                    }
                    var tid3 = DateTime.Now.Subtract(start3);
    
                    var start = DateTime.Now;
                    for (int i = 0; i < 1000; i++ )
                    {
                        engine.Execute("console.logs(JSON.stringify({v1:4,v2:['a','bc', 'de', {f:'g'}],h:1,i:2,j:3,k:4}));");
                    }
                    var tid = DateTime.Now.Subtract(start);
                    var start2 = DateTime.Now;
                    for (int i = 0; i < 1000; i++)
                    {
                        engine.Execute("console.log({v1:4,v2:['a','bc', 'de', {f:'g'}],h:1,i:2,j:3,k:4});");
                    }
                    var tid2 = DateTime.Now.Subtract(start2);
    
    
                    
                    Console.WriteLine("static tok : " + tid.ToString());
                    Console.WriteLine("dynamic tok : " + tid2.ToString());
                    Console.WriteLine("Console.Write tok: " + tid3.ToString());
                    string str;
                    while ((str = Console.ReadLine()) != "end")
                    {
                        engine.Execute(str);
                    }
                }
    
    Getting the result:
    static tok : 00:00:05.3335333
    dynamic tok : 00:00:05.6545654
    Console.Write tok: 00:00:02.4172417
    So the "static" console.logs alternative to dynamic only slightly cheaper.

    In the logging example - I should just pass the jsonstring to .net, but generally, if I need to send a literal to .net in a predefined structure, it's ok to use dynamic. I think, however, there is one weakness in GetDynamicMemberNames: that you don't know if its an array or object. Is there another way of knowing?

    0 0

    So the "static" console.logs alternative to dynamic only slightly cheaper.

    Right, but that's after you minimized your usage of the dynamic infrastructure. In your original implementation you declared o as a dynamic parameter, which led to unnecessary dynamic calls to GetDynamicMemberNames() and ToString(). You also redundantly evaluated o[egenskap] several times; each of those indexing operations is a dynamic call into the underlying script engine.

    ​​I think, however, there is one weakness in GetDynamicMemberNames: that you don't know if its an array or object. Is there another way of knowing?

    For arrays, GetDynamicMemberNames() returns the valid indices as strings. If that's not what you're looking for, remember that examining script objects is often easiest to do in script code:
    dynamic isScriptArray = engine.Evaluate("(function (x) { return x instanceof Array; })");
    
    var result = engine.Evaluate("[1,2,3,4,5]");
    if (isScriptArray(result)) {
        // do something
    }
    Cheers!

    0 0

    Hi guys,

    Currently i faced with exception on MVC 4 app:
    Cannot load V8 interface assembly; verify that the following files are installed with your application: ClearScriptV8-32.dll, ClearScriptV8-64.dll, v8-ia32.dll, v8-x64.dll
    I run it on Win7 x64 on VS 2013 with installed all C++ packages.
    All dlls (ClearScriptV8-32.dll, ClearScriptV8-64.dll, v8-ia32.dll and v8-x64.dll) included in project as Content and marked do not copy (as marked in some discussions before).

    What`s wrong? what i need to make it works?

    0 0

    Hi,

    There is legacy application that wrote on delphi. It uses with a VB Script Engine.
    The delphi code call VBScript function by dispatchId that cached during init script engine.
    Is there a way in ClearScript call function by disptach id

    Thanks.

older | 1 | .... | 14 | 15 | (Page 16) | 17 | 18 | .... | 115 | newer