unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Experiment with threads - no concurrency?
@ 2021-09-06 14:35 Arthur Miller
  2021-09-06 15:17 ` Stefan Monnier
  2021-09-06 15:47 ` Eli Zaretskii
  0 siblings, 2 replies; 10+ messages in thread
From: Arthur Miller @ 2021-09-06 14:35 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1570 bytes --]


I did a little experiment today. I wanted to count frequency of Emacs functions
usage. So I started by indexing all functions and macros.

Since it is kind of lot's of I/O and independent tasks to do, I thought threads
could come handy. However I see no difference from sequential code.

I tried different versions, one where I did a single call to
directory-files-recursively, and than used one thread per file, to parse each
file separately, in own thread, but it was the slowest version. When I used to
code in Java long time ago, I used to see improvement in this kind of jobs due
to I/O. Maybe I am missunderstanding Emacs threads here?

In second version, I do two calls to directory-files-recursively, each in it's
own thread and use only two threads to do all the work, one per list. It is
slightly faster, but just slightly and still slower than pure sequential version.

I have also inserted thread-yield statements so that all threads get chance to
run, but I see very little difference. Measured difference is probably due to
system fluctuation, rather than truly beacuse of thread scheduling (~0.1 sec on
a job of ~10 secs).

So, how to use threads in Emacs correctly? Is this me or is there just no
benefit of current thread implementation in Emacs? Sorry I don't mean to be rude
on thread implementation, but I am in doubt, should I just forgett about threads
or is there something I missunderstand about how to use them correctly?

The attached program is just about parsing files in emacs lisp dir for function
and macro defs (no frequency counting).


[-- Attachment #2: func-freq.el --]
[-- Type: text/plain, Size: 3579 bytes --]

;;; func-freq.el ---                                 -*- lexical-binding: t; -*-

;; Copyright (C) 2021  Arthur Miller

;; Author: Arthur Miller <arthur.miller@live.com>
;; Keywords: 

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; 

;;; Code:
(defun ff-print (map)
  (maphash (lambda (k v) (print (format "%s: %s" k v))) map))

(defun ff-collect-funcs-and-macros (src &optional keyword)
  (with-temp-buffer
    (insert-file-contents-literally src)
    (goto-char (point-min))
    (let (sxp features)
      (while (setq sxp (ignore-errors (read (current-buffer))))
        (when (and (listp sxp) (equal (car sxp) keyword))
          (push (cadr sxp) features)))
        features)))

(defun ff-freq-seq (dir-tree)
  (let ((fmap (make-hash-table :test 'equal))
        (mmap (make-hash-table :test 'equal))
        (srcs (directory-files-recursively dir-tree "\\.el$")))
    (dolist (src srcs)
      (dolist (f (ff-collect-funcs-and-macros src 'defun))
        (puthash f 0 fmap))
      (dolist (f (ff-collect-funcs-and-macros src 'defmacro))
        (puthash f 0 mmap)))))

(defun ff-freq-thr (dir-tree)
  (let (threads
        (fmap (make-hash-table :test 'equal))
        (mmap (make-hash-table :test 'equal))
        (srcs (directory-files-recursively dir-tree "\\.el$")))
    (dolist (src srcs)
      (push (make-thread #'(lambda () 
                             (dolist (f (ff-collect-funcs-and-macros src 'defun))
                               (puthash f 0 fmap)
                               ;;(thread-yield)
                               )
                             (dolist (f (ff-collect-funcs-and-macros src 'defmacro))
                               (puthash f 0 mmap)
                               ;;(thread-yield)
                               ))) threads))
    (dolist (thread threads)
      (thread-join thread))))

(defun ff-collect-macros (dir-tree map)
  (let ((srcs (directory-files-recursively dir-tree "\\.el$")))
    (dolist (src srcs)
      (dolist (f (ff-collect-funcs-and-macros src 'defmacro))
        (puthash f 0 map)
        ;;(thread-yield)
        ))))

(defun ff-collect-functions (dir-tree map)
  (let ((srcs (directory-files-recursively dir-tree "\\.el$")))
    (dolist (src srcs)
      (dolist (f (ff-collect-funcs-and-macros src 'defun))
        (puthash f 0 map)
        ;;(thread-yield)
        ))))

(defun ff-freq-thr2 (dir-tree)
  (let (fthr mthr
        (fmap (make-hash-table :test 'equal))
        (mmap (make-hash-table :test 'equal)))
    (setq mthr (make-thread #'(lambda () (ff-collect-macros dir-tree fmap))))
    (setq fthr (make-thread #'(lambda () (ff-collect-functions dir-tree mmap))))
    (thread-join mthr)
    (thread-join fthr)))

(benchmark-run 3 (ff-freq-seq (expand-file-name "~/repos/emacs/lisp")))
(benchmark-run 3 (ff-freq-thr (expand-file-name "~/repos/emacs/lisp")))
(benchmark-run 3 (ff-freq-thr2 (expand-file-name "~/repos/emacs/lisp")))

(provide 'func-freq)
;;; func-freq.el ends here

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-09-06 18:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-06 14:35 Experiment with threads - no concurrency? Arthur Miller
2021-09-06 15:17 ` Stefan Monnier
2021-09-06 16:35   ` Arthur Miller
2021-09-06 17:31     ` Eli Zaretskii
2021-09-06 17:38   ` T.V Raman
2021-09-06 18:11     ` Arthur Miller
2021-09-06 15:47 ` Eli Zaretskii
2021-09-06 16:40   ` Arthur Miller
2021-09-06 17:33     ` Eli Zaretskii
2021-09-06 18:10       ` Arthur Miller

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).