Re: Why are long functions slower?

2017-10-15 Thread Eduardo A . Bustamante López
On Sun, Oct 15, 2017 at 01:53:15PM -0500, Eduardo A. Bustamante López wrote:
[...]
> From what I can tell, most of the overhead should be in `execute_function' 
> (execute_cmd.c):
> 
> - calls `tc = (COMMAND *)copy_command (function_cell (var));' for every 
> function invocation. For large functions, this
>   means a lot of copying. 
> 
> - It also calls `dispose_command(tc)' to dispose of this temporary COMMAND 
> structure.

Just out of curiosity, I hacked bash to remove the copy_command /
dispose_command overhead (which AFAICT breaks the handling of errexit for 
functions).

I ran the script at the bottom (N = 100). The results:

- Unpatched bash, -O2 & bash malloc: ~263.78ms per function invocation
- Patched bash, -O2 & bash malloc: ~3.36ms per function invocation
- Unpatched bash, -O2 & glibc malloc (2.26-0ubuntu2): ~1.5ms per function 
invocation

So my current guess is that you're comparing a bash built with the internal 
malloc, vs bash built to use glibc's malloc.


BTW, Chet: Is there a reason for all the object copying / destruction, other 
than setting the `flags' attribute in the
COMMAND structure?


dualbus@ubuntu:~/src/gnu$ for bash in ./build/bash ./build-patched/bash; do 
time $bash ~/bash-func/script ; done

real0m26.378s
user0m26.368s
sys 0m0.004s

real0m0.336s
user0m0.332s
sys 0m0.000s

# I ran this after the two above; unpatched bash, --without-bash-malloc
dualbus@ubuntu:~/src/gnu$ for bash in ./build-libcmalloc/bash; do time $bash 
~/bash-func/script ; done

real0m0.150s
user0m0.148s
sys 0m0.000s


dualbus@ubuntu:~/src/gnu$ (cd bash; PAGER= git diff)
diff --git a/execute_cmd.c b/execute_cmd.c
index 8d38378e..cdb2ce6d 100644
--- a/execute_cmd.c
+++ b/execute_cmd.c
@@ -4724,7 +4724,7 @@ execute_function (var, words, flags, fds_to_close, async, 
subshell)
   GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
 #endif
 
-  tc = (COMMAND *)copy_command (function_cell (var));
+  tc = function_cell (var);
   if (tc && (flags & CMD_IGNORE_RETURN))
 tc->flags |= CMD_IGNORE_RETURN;
 
@@ -4743,7 +4743,6 @@ execute_function (var, words, flags, fds_to_close, async, 
subshell)
   unwind_protect_int (function_line_number);
   unwind_protect_int (return_catch_flag);
   unwind_protect_jmp_buf (return_catch);
-  add_unwind_protect (dispose_command, (char *)tc);
   unwind_protect_pointer (this_shell_function);
   unwind_protect_int (funcnest);
   unwind_protect_int (loop_level);


dualbus@ubuntu:~/src/gnu$ cat ~/bash-func/script
f() {
return
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 
: : : : : : : : : : : : : : : : 

Re: Why are long functions slower?

2017-10-15 Thread Eduardo A . Bustamante López
On Tue, Oct 10, 2017 at 03:46:38PM +0200, Bernhard M. Wiedemann wrote:
> Hi,
> 
> today I was debugging performance issues with a 200KB bash script [1]
> with bash-4.3 and 4.4
> and it seems that much of it came from a function call that took 0.1
> seconds (and it was done in a loop for 37000 files)
> even though it basically just consisted of an
>   if [[ 0 != 0 ]] ; then

Hi Bernhard,

I have some questions:

1. Which specific versions of 4.3 and 4.4?
2. Did you compile bash from source? (if so, what did you use for CFLAGS and 
the configure script parameters? are you
   using bash's malloc or the system malloc?)
3. ... Or did you use a distro package? (if so, can you provide links to the 
specific packages used?)
4. Do you have precise timing information? How specifically did you test? How 
many iterations? etc


From what I can tell, most of the overhead should be in `execute_function' 
(execute_cmd.c):

- calls `tc = (COMMAND *)copy_command (function_cell (var));' for every 
function invocation. For large functions, this
  means a lot of copying. 

- It also calls `dispose_command(tc)' to dispose of this temporary COMMAND 
structure.


There were no changes there between 4.3.30 and 4.4.12. The only noticeable 
change I can see is the addition of the
`restore_funcarray_state' function and `struct func_array_state', used to 
restore the contents of FUNCNAME between
function invocations. Although from my observation, this doesn't seem to have a 
noticeable effect in performance.


signature.asc
Description: PGP signature


Re: PDF Version - Page Numbers Incorrect

2017-10-15 Thread Eduardo A . Bustamante López
On Sat, Oct 14, 2017 at 09:25:26PM -0400, Josh Blagden wrote:
> Hi GNUs,  
> 
>     The page numbers in the Table of Contents are incorrect. For
> example, section 3.2.6, titled "GNU Parallel" is on page 21, not page
> 22. Also, section 3.6, titled "Redirections" is on page 38, not page 32.
> I assume that this is merely due to the author making additions to the
> manual without correcting the page numbers in the PDF.

Hi Josh,

I'm guessing you're talking about the Bash reference manual. What source file 
are you using? I'm looking at:
, and the TOC lists 3.2.6 in 
page 15, and 3.6 is listed as being in
page 32. I see that both sections begin in the advertised page number.

I also checked against the `devel' branch in git, by running:

$ ./configure --silent && make -s -C doc/ bashref.pdf

(NOTE: you need the `texinfo' and `texlive' packages to be able to generate the 
PDF file from source).

In the generated file (doc/bashref.pdf), 3.2.6 is listed in page 16, and 3.6 in 
page 33. Both indicate the correct page
number.


By the way, are you checking against the page number in the page header, or the 
"PDF page number"? I noticed that the
PDF page number doesn't match the page number in the page header, which seems 
to be a limitation of the tool used to
generate the file (i.e. texi2dvi). In both cases (bash.pdf from www.gnu.org and 
doc/bashref.pdf), the PDF page number is
offset by a constant factor of +6 (i.e. PDF's pg. 22 is doc's pg. 16; PDF's pg. 
38 is doc's pg. 32).

I read 
, 
but I don't see any mention of an
option to control the page number offset described above.

Looking around, I see that this is a common problem where the logical page 
number doesn't match the PDF physical page
number. It seems there are some PDF readers that allow you to switch between 
page numbering schemes [1]. Sadly, the ones
I've tried (evince: libevdocument3.so.4, libevview3.so.3; xpdf: 
libpoppler.so.68 [2], firefox: pdf.js). If this is the
problem you're seeing, I don't think there's a solution, other than using a PDF 
reader that supports using logical page
numbers.


[1] 
[2] 


signature.asc
Description: PGP signature


PDF Version - Page Numbers Incorrect

2017-10-15 Thread Josh Blagden
Hi GNUs,  

    The page numbers in the Table of Contents are incorrect. For
example, section 3.2.6, titled "GNU Parallel" is on page 21, not page
22. Also, section 3.6, titled "Redirections" is on page 38, not page 32.
I assume that this is merely due to the author making additions to the
manual without correcting the page numbers in the PDF.

I don't have all of the corrections, and I don't currently have time to
go through the manual and create a list of corrections. If someone else
has time and makes the list of corrections, that would be great. If I
have time in the next week or two, I might work on the list of
corrections. Consquently, if someone else does complete a list of
corrections in the next 2-3 weeks, I would like to be notified so I'll
know that my list will no longer be needed.


Thanks!


Josh Blagden

 5.