Loading ...
Sorry, an error occurred while loading the content.

Re: [jslint] slice method appears slower in loops than incrementally listing array indexes

Expand Messages
  • Marcel Duran
    Hi Austin, It s hard to tell why it s slower/faster without checking the algorithm implemented for slice on different engines. I did some background research
    Message 1 of 5 , Sep 3, 2010
    • 0 Attachment
      Hi Austin,

      It's hard to tell why it's slower/faster without checking the algorithm
      implemented for slice on different engines. I did some background research
      on implementations of String.indexOf (
      http://www.javascriptrules.com/2009/08/12/string-searching-algorithms-in-javascript-engines/),
      you probably need to do something similar to understand why, unfortunately
      you won't be able to check those closed-source engines.

      BTW, looking at your example, have you considered regular expression or even
      String.indexOf, you could save some time by not splitting a long string into
      array.

      Regarding your tests, could you share it with the list? Maybe create a new
      test suite on http://jsperf.com/


      <http://jsperf.com/>Best,

      Marcel

      On Fri, Sep 3, 2010 at 1:35 PM, Cheney, Edward A SSG RES USAR <
      austin.cheney@...> wrote:

      >
      >
      > Group,
      >
      > I am trying to figure out why slice appears to be slower when executed upon
      > a large string than merely pointing to a group of indexes. My presumption is
      > that slice should be faster, but in my tests it is definitely slower. Here
      > are some code examples:
      >
      > var a, i, x = "some large string of greater than 150kb", y = x.split(''), z
      > = y.length;
      > for (i = 0, i < z; i += 1) {
      > if (y[i] + y[i + 1].toLowerCase() + y[i + 2].toLowerCase() + y[i +
      > 3].toLowerCase() + y[i + 4].toLowerCase() + y[i + 5].toLowerCase() + y[i +
      > 6].toLowerCase() === "<style") {
      > a = "some value";
      > }
      > }
      > for (i = 0, i < z; i += 1) {
      > if (x.slice(i, i + 7) === "<style") {
      > a = "some value";
      > }
      > }
      >
      > The second loop is much easier to read and I presume it would be faster
      > because it is searching an index of a string, but it is only performing that
      > search once per iteration of the loop. The first loop is ugly to look at,
      > but appears faster in Firefox and Opera, which is surprising because it is
      > performing 7 different look ups into an array per loop iteration. It is
      > further surprising considering that large data segments would presumed to be
      > more memory efficient as a joined string opposed to associating each
      > character with an array index. The larger the tested string the more
      > disparaging the results become.
      >
      > My question is why is the second loop, the pretty one, slower than the
      > first loop? Even more strange I have found an exception to this test where
      > the second loop becomes faster than the first loop only if the value of Z is
      > subject to change per loop iteration, but the difference of speed in this
      > exception is less than the difference of speed evident in the stated
      > examples.
      >
      > Thanks,
      >
      > Austin
      > http://prettydiff.com/
      >
      >



      --
      Marcel Duran


      [Non-text portions of this message have been removed]
    • Cheney, Edward A SSG RES USAR
      Marcel, I did consider those. The limitation of indexOf method is that it can only be used once without altering your source data, and regular expression
      Message 2 of 5 , Sep 3, 2010
      • 0 Attachment
        Marcel,

        I did consider those. The limitation of indexOf method is that it can only be used once without altering your source data, and regular expression would certainly be faster, but there is no native method for using a regular expression to return a list of indexes.

        As far as which tests I was using I was altering the type_define function of the markup_beauty function to obtain both tests. I used the it function of the markupmin function to discover the exception situation. Both of those scripts are components of a Pretty Diff tool I maintain at prettydiff.com

        http://prettydiff.com/markup_beauty.js
        http://prettydiff.com/markupmin.js

        Thanks,
        Austin
      • Marcel Duran
        What if you use regular expression with String.replace, you have a list of index plus you can alter the source data. Ex: var re = /
        Message 3 of 5 , Sep 4, 2010
        • 0 Attachment
          What if you use regular expression with String.replace, you have a list of
          index plus you can alter the source data. Ex:

          var re = /<style/gi,
          str = 'foobar<style foo>foobar</style>foobar<script
          bar>foobar</script><STYLE foo>foobar</STYLE>foobar',
          res = str.replace(re, function (match, index, source) {
          print(index); // 6 then 64
          return '*' + match + '*';
          });

          print(res); // foobar*<style* foo>foobar</style>foobar<script
          bar>foobar</script>*<STYLE* foo>foobar</STYLE>foobar


          Best,

          Marcel


          On Fri, Sep 3, 2010 at 7:55 PM, Cheney, Edward A SSG RES USAR <
          austin.cheney@...> wrote:

          >
          >
          > Marcel,
          >
          > I did consider those. The limitation of indexOf method is that it can only
          > be used once without altering your source data, and regular expression would
          > certainly be faster, but there is no native method for using a regular
          > expression to return a list of indexes.
          >
          > As far as which tests I was using I was altering the type_define function
          > of the markup_beauty function to obtain both tests. I used the it function
          > of the markupmin function to discover the exception situation. Both of those
          > scripts are components of a Pretty Diff tool I maintain at prettydiff.com
          >
          > http://prettydiff.com/markup_beauty.js
          > http://prettydiff.com/markupmin.js
          >
          > Thanks,
          > Austin
          >
          >



          --
          Marcel Duran


          [Non-text portions of this message have been removed]
        • sandyhead25
          Marcel, String replace would certainly be faster, because such instructions pass to the same code base on which the JavaScript interpreter sits. String
          Message 4 of 5 , Sep 5, 2010
          • 0 Attachment
            Marcel,

            String replace would certainly be faster, because such instructions pass to the same code base on which the JavaScript interpreter sits. String replace does not provide an index for its global matches so as to allow multiple instructions to execute on each match or pull each match into an empty array. In not for such conditions I would certainly use the replace method.

            It should be noted that while it is possible to pass a function with arguments into the replace method one should never do so. This essentially creates a whole through the interpreter to the underling code base. That means that if you can inject code into one of the function arguments you can pass that code through the JavaScript interpreter to possibly compromise the executing software. I would gladly sacrifice a measurable amount of performance as a general best practice to prevent potential code injection.

            Thanks,

            Austin
            http://prettydiff.com/
          Your message has been successfully submitted and would be delivered to recipients shortly.