<p>I had this problem on Ubuntu 18.04. I updated the gem</p> <pre class="lang-bash prettyprint-override"><code>sudo gem install rails sudo gem install jekyll sudo gem install jekyll bundler cd ~/desiredFolder jekyll new <foldername> cd <foldername> OR bundle init bundle install bundle add jekyll bundle exec jekyll serve </code></pre> Logger slf4j advantages of formatting with {} instead of string concatenation

instead of

logger.debug("Temperature set to"+ t + ". Old temperature was " + oldT);

In my case this worked:

    I think it's about speed optimization because parameters evaluation (and string concatenation) could be avoided in runtime depending on a config file. But only two parameters are possible, then sometimes there is no other choice than string concatenation. Needing views on this issue.

140466 次浏览
  • cd /usr/bin
  • touch Gemfile
  • It is about string concatenation performance. It's potentially significant if your have dense logging statements.

  • Now you can then run bundle install.
  • (Prior to SLF4J 1.7) But only two parameters are possible

    ut only two parameters are possible

    Because the vast majority of logging statements have 2 or fewer parameters, so SLF4J API up to version 1.6 covers (only) the majority of use cases. The API designers have provided overloaded methods with varargs parameters since API version 1.7.

    Because the vast majority of logging statements have 2 or fewer parameters, so SLF4J API up to version 1.6 covers (only) the majority of use cases. The API designers have provided overloaded methods with varargs parameters since API version 1.7.

    For those cases where you need more than 2 and you're stuck with pre-1.7 SLF4J, then just use either string concatenation or new Object[] { param1, param2, param3, ... }. There should be few enough of them that the performance is not as important.

    You can provide any number of arguments. Note that if you use an old version of sljf4j and you have more than two arguments to {}, you must use the new Object[]{a,b,c,d} syntax to pass an array instead. See e.g. http://slf4j.org/apidocs/org/slf4j/Logger.html#debug(java.lang.String, java.lang.Object[]).

    Why do all script files start with

    #!/bin/sh
    

    Regarding the speed: Ceki posted a benchmark a while back on one of the lists.

    or with

    #!/bin/csh
    

    Is that required? What's the purpose of this? And what's the difference between the two?

    Another alternative is String.format(). We are using it in jcabi-log (static utility wrapper around slf4j).

    Logger.debug(this, "some variable = %s", value);
    
    able = %s", value);

    It's much more maintainable and extendable. Besides, it's easy to translate.

    This concept extends to other scripts too. For instance if you program in Python you'd put

     #!/usr/bin/python
    

    This is known as a Shebang:

    at the top of your Python program

    http://en.wikipedia.org/wiki/Shebang_(Unix)

    I think from the author's point of view, the main reason is to reduce the overhead for string concatenation.I just read the logger's documentation, you could find following words:

    /**
    * <p>This form avoids superfluous string concatenation when the logger
    * is disabled for the DEBUG level. However, this variant incurs the hidden
    * (and relatively small) cost of creating an <code>Object[]</code> before
    invoking the method,
    * even if this logger is disabled for DEBUG. The variants taking
    * {@link #debug(String, Object) one} and {@link #debug(String, Object, Object) two}
    * arguments exist solely in order to avoid this hidden cost.</p>
    */
    *
    * @param format    the format string
    * @param arguments a list of 3 or more arguments
    */
    public void debug(String format, Object... arguments);
    

    #!interpreter [optional-arg]

    Compliant logging is highly important for application development, as it affects performance.

    A shebang is only relevant when a script has the execute permission (e.g. chmod u+x script.sh).

    When a shell executes the script it will use the specified interpreter.

    The mentioned non-compliant logging is resulting with redundant toString() method invocation on each call, and is resulting with redundant temporary memory allocation and CPU processing, as can be seen at example high scale test execution, where we can take a look on redundant allocated temporary memory: Memory

    Example:

    #!/bin/bash
    # file: foo.sh
    echo 1
    
    
    $ chmod u+x foo.sh
    $ ./foo.sh
    1
    

    Look on method profiling:
    Look on method profiling

    lt="Memory" />

    Look on method profiling:
    Look on method profiling

    Note: I am the author of this blog post, Logging impact on application performance.

    A trace like this will concatenate the string even if the trace will be ignored, which is a waste of time :

    The #! line tells the kernel (specifically, the implementation of the execve system call) that this program is written in an interpreted language; the absolute pathname that follows identifies the interpreter. Programs compiled to machine code begin with a different byte sequence -- on most modern Unixes, 7f 45 4c 46 (^?ELF) that identifies them as such.

    logger.debug("Temperature set to"+ t + ". Old temperature was " + oldT);

    A trace like this will be ignored at no cost :

    You can put an absolute path to any program you want after the #!, as long as that program is not itself a #! script. The kernel rewrites an invocation of

    ./script arg1 arg2 arg3 ...
    

    logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);

    where ./script starts with, say, #! /usr/bin/perl, as if the command line had actually been

    /usr/bin/perl ./script arg1 arg2 arg3
    

    If you have a lot of debug traces that you ignore in production, using {} is definitely better as it has no impact on performance.

    Or, as you have seen, you can use #! /bin/sh to write a script intended to be interpreted by sh.

    ! /usr/bin/perl, as if the command line had actually been

    /usr/bin/perl ./script arg1 arg2 arg3
    

    Or, as you have seen, you can use #! /bin/sh to write a script intended to be interpreted by sh.

    The #! line is only processed if you directly invoke the script (./script on the command line); the file must also be executable (chmod +x script). If you do sh ./script the #! line is not necessary (and will be ignored if present), and the file does not have to be executable. The point of the feature is to allow you to directly invoke interpreted-language programs without having to know what language they are written in. (Do grep '^#!' /usr/bin/* -- you will discover that a great many stock programs are in fact using this feature.)

    Here are some rules for using this feature:

      The #! line is only processed if you directly invoke the script (./script on the command line); the file must also be executable (chmod +x script). If you do sh ./script the #! line is not necessary (and will be ignored if present), and the file does not have to be executable. The point of the feature is to allow you to directly invoke interpreted-language programs without having to know what language they are written in. (Do grep '^#!' /usr/bin/* -- you will discover that a great many stock programs are in fact using this feature.)

      Here are some rules for using this feature:

      • The #! must be the very first two bytes in the file. In particular, the file must be in an ASCII-compatible encoding (e.g. UTF-8 will work, but UTF-16 won't) and must not start with a "byte order mark", or the kernel will not recognize it as a #! script.
      • The path after #! must be an absolute path (starts with /). It cannot contain space, tab, or newline characters.
      • It is good style, but not required, to put a space between the #! and the /. Do not put more than one space there.
      • The #! must be the very first two bytes in the file. In particular, the file must be in an ASCII-compatible encoding (e.g. UTF-8 will work, but UTF-16 won't) and must not start with a "byte order mark", or the kernel will not recognize it as a #! script.
      • The path after #! must be an absolute path (starts with /). It cannot contain space, tab, or newline characters.
      • You cannot put shell variables on the #! line, they will not be expanded.
      • It is good style, but not required, to put a space between the #! and the /. Do not put more than one space there.
      • You cannot put shell variables on the #! line, they will not be expanded.
      • You can put one command-line argument after the absolute path, separated from it by a single space. Like the absolute path, this argument cannot contain space, tab, or newline characters. Sometimes this is necessary to get things to work (#! /usr/bin/awk -f), sometimes it's just useful (#! /usr/bin/perl -Tw). Unfortunately, you cannot put two or more arguments after the absolute path.
      • Some people will tell you to use #! /usr/bin/env interpreter instead of #! /absolute/path/to/interpreter. This is almost always a mistake. It makes your program's behavior depend on the $PATH variable of the user who invokes the script. And not all systems have env in the first place.
      • You can put one command-line argument after the absolute path, separated from it by a single space. Like the absolute path, this argument cannot contain space, tab, or newline characters. Sometimes this is necessary to get things to work (#! /usr/bin/awk -f), sometimes it's just useful (#! /usr/bin/perl -Tw). Unfortunately, you cannot put two or more arguments after the absolute path.
      • Programs that need setuid or setgid privileges can't use #!; they have to be compiled to machine code. (If you don't know what setuid is, don't worry about this.)
    • Some people will tell you to use #! /usr/bin/env interpreter instead of #! /absolute/path/to/interpreter. This is almost always a mistake. It makes your program's behavior depend on the $PATH variable of the user who invokes the script. And not all systems have env in the first place.
    • Programs that need setuid or setgid privileges can't use #!; they have to be compiled to machine code. (If you don't know what setuid is, don't worry about this.)

    Regarding csh, it relates to sh roughly as Nutrimat Advanced Tea Substitute does to tea. It has (or rather had; modern implementations of sh have caught up) a number of advantages over sh for interactive usage, but using it (or its descendant tcsh) for scripting is sh0. If you're new to shell scripting in general, I strongly recommend you ignore it and focus on sh. If you are using a csh relative as your login shell, switch to bash or zsh, so that the interactive command language will be the same as the scripting language you're learning.