【问题标题】:Generate a random string in the fastest way以最快的方式生成随机字符串
【发布时间】:2016-09-23 21:29:36
【问题描述】:

我目前正在使用这个:

(defvar my-charset
  (eval-when-compile
    (concat (number-sequence 48 57) (number-sequence 65 90) (number-sequence 97 122)))
  "Char set in terms of number list.")
(defvar my-charset-length
  (eval-when-compile
    (length (concat (number-sequence 48 57) (number-sequence 65 90) (number-sequence 97 122))))
  "Length of my-charset.")

(defun my-generate-string (&optional max-length min-length)
  "Generate a random string."
  (let (string)
    (dotimes (_i (+ (random (- (or max-length 10) (or min-length 5) -1)) (or min-length 5)))
      (push (aref my-charset (random my-charset-length)) string))
    (concat string)))

有什么方法可以加快速度?

或者任何其他更快地生成字符串的方法?

【问题讨论】:

  • 你需要它有多“随机”?

标签: string random elisp


【解决方案1】:

通过更有效地使用数据(和控制)结构可以获得少量性能提升。

(defconst our-charset "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
(defconst our-charset-length (length our-charset))

(defun my-generate-string (&optional max-length min-length)
  "Generate a random string."
  (let (string)
    (dotimes (_i (+ (random (- (or max-length 10) (or min-length 5) -1)) (or min-length 5)))
      (push (aref our-charset (random our-charset-length)) string))
    (concat string)))

(defun our-generate-string (&optional max-length min-length)
  (let* ((max-length (or max-length 10))
         (min-length (or min-length 5))
         (length (+ min-length (random (- max-length min-length -1))))
         (string (make-string length ?0)))
    (dotimes (i length string)
      (aset string i
            (aref our-charset (random our-charset-length))))))

(defmacro measure-time (&rest body)
  `(let ((time (current-time)))
     ,@body
     (float-time (time-since time))))

(/
 (apply #'+
        (mapcar
         (lambda (ignore) (measure-time (my-generate-string 1000 999)))
         (number-sequence 0 999)))
 1000)
;; 0.0018966329990000002

(/
 (apply #'+
        (mapcar
         (lambda (ignore) (measure-time (our-generate-string 1000 999)))
         (number-sequence 0 999)))
 1000)
;; 0.0009833975549999997

您的结果可能因硬件和随机性而异,但our-generate-string 应该更快。

您可能还想稍微调整一下您的调用约定。

(defun our-randomized-string (charset length)
  (let ((charset-length (length charset))
        (string (make-string length ?0)))
    (dotimes (i length string)
      (aset string i
            (aref charset (random charset-length))))))

(/
 (apply #'+
        (mapcar
         (lambda (ignore) (measure-time (our-randomized-string our-charset 1000)))
         (number-sequence 0 999)))
 1000)
 ;; 0.0009300809320000015

请注意,our-randomized-string 不一定比our-generate-string 快,但能够在函数外部修复参数而不是在内部确定它们可能最终会带来好处。在这个版本中,字符集的交换也比其他版本更容易。

【讨论】:

    猜你喜欢
    • 2015-07-17
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 2017-08-01
    相关资源
    最近更新 更多