;Benchmark:
;CL-USER> (time (loop repeat 100000 do (generate-random-text 100)))
;Evaluation took:
; 1.375 seconds of real time
; 1.375000 seconds of total run time (1.375000 user, 0.000000 system)
; [ Run times consist of 0.080 seconds GC time, and 1.295 seconds non-GC time. ]
; 100.00% CPU
; 3,299,809,761 processor cycles
; 136,798,984 bytes consed
;;; Here's a slightly more efficient implementation:
(defun generate-random-text (length &optional (valid-chars +valid-chars+))
(let ((string (make-string length)))
(dotimes (i length)
(setf (aref string i) (pick-random valid-chars)))))
;CL-USER> (time (loop repeat 100000 do (generate-random-text 100)))
;Evaluation took:
; 0.703 seconds of real time
; 0.703125 seconds of total run time (0.687500 user, 0.015625 system)
; 100.00% CPU
; 1,684,737,900 processor cycles
; 41,602,096 bytes consed
>>7
I didn't benchmark a single call as it would have been hard to tell how much it took (it's just too fast, and inconclusive in a multi-tasked environment). But if you want it that much, here it is:
CL-USER> (time (generate-random-text 100))
Evaluation took:
0.000 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
100.00% CPU
18,873 processor cycles
0 bytes consed
public String gibberjabber(String in, int x, Random rand) { return ( x <= 0 ? in : gibberjabber(in+"1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".charAt(rand.nextInt()%62), x-1, rand) ); }
I think. You'll have to import java.util.Random.
To use it: this.gibberjabber("", x, new Random());
Name:
Anonymous2010-01-12 15:38
sub babble($){pack "C*",map{0x20+rand*0x40}1..shift}
Hmm, my code isn't as efficient as it could be according to the disassembly, that ELT doesn't get transformed into an AREF by the compiler as it doesn't know the type. Here's a quickly hacked up version that speeds it up some 4 times:
;;; Even more efficient implementation:
(defconstant +valid-chars+ "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjklmopqrst")
CL-USER> (time (loop repeat 100000 do (generate-random-alphanumerics 100)))
Evaluation took:
0.172 seconds of real time
0.171875 seconds of total run time (0.171875 user, 0.000000 system)
[ Run times consist of 0.015 seconds GC time, and 0.157 seconds non-GC time. ]
100.00% CPU
436,756,122 processor cycles
41,596,880 bytes consed
CL-USER> (time (generate-random-alphanumerics 100))
Evaluation took:
0.000 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
100.00% CPU
15,948 processor cycles
0 bytes consed
"4tZXRLNVKpC5oPQgQpSsDpX87aYZs88GOR1bSamksJ7X5tU5SPA717sKEjHlXYe8KGQAL28ZPYfVlO6h0JlrDH9JIdMtPS7Lp2CQ"
CL-USER> (disassemble #'generate-random-alphanumerics)
; disassembly for GENERATE-RANDOM-ALPHANUMERICS
; 23F16042: 8BFA MOV EDI, EDX ; no-arg-parsing entry point
; 044: 8D4204 LEA EAX, [EDX+4]
; 047: 8D700F LEA ESI, [EAX+15]
; 04A: 83E6F8 AND ESI, -8
; 04D: 892D2C041022 MOV [#x2210042C], EBP
; 053: 033578D14100 ADD ESI, [#x41D178] ; _boxed_region
; 059: 3B357CD14100 CMP ESI, [#x41D17C]
; 05F: 7607 JBE L0
; 061: E85AC34FDC CALL #x4123C0 ; _alloc_overflow_esi
; 066: EB12 JMP L1
; 068: L0: 333578D14100 XOR ESI, [#x41D178] ; _boxed_region
; 06E: 313578D14100 XOR [#x41D178], ESI ; _boxed_region
; 074: 333578D14100 XOR ESI, [#x41D178] ; _boxed_region
; 07A: L1: 8D7607 LEA ESI, [ESI+7]
; 07D: C646F9AA MOV BYTE PTR [ESI-7], 170
; 081: 8956FD MOV [ESI-3], EDX
; 084: 312D2C041022 XOR [#x2210042C], EBP
; 08A: 7402 JEQ L2
; 08C: CC09 BREAK 9 ; pending interrupt trap
; 08E: L2: C745F800000000 MOV DWORD PTR [EBP-8], 0
; 095: EB77 JMP L5
; 097: L3: 8B051860F123 MOV EAX, [#x23F16018] ; '*RANDOM-STATE*
; 09D: 8B40FD MOV EAX, [EAX-3]
; 0A0: 8B4007 MOV EAX, [EAX+7]
; 0A3: 8945FC MOV [EBP-4], EAX
; 0A6: 8B5DFC MOV EBX, [EBP-4]
; 0A9: 8B4B09 MOV ECX, [EBX+9]
; 0AC: 81F970020000 CMP ECX, 624
; 0B2: 7509 JNE L4
; 0B4: 8BC3 MOV EAX, EBX
; 0B6: E8DCA30EFE CALL #x22000497 ; RANDOM-MT19937-UPDATE
; 0BB: 31C9 XOR ECX, ECX
; 0BD: L4: 8B548B0D MOV EDX, [EBX+ECX*4+13]
; 0C1: C1EA0B SHR EDX, 11
; 0C4: 33548B0D XOR EDX, [EBX+ECX*4+13]
; 0C8: 8BC2 MOV EAX, EDX
; 0CA: 41 INC ECX
; 0CB: C1E007 SHL EAX, 7
; 0CE: 894B09 MOV [EBX+9], ECX
; 0D1: 2580562C9D AND EAX, 2636928640
; 0D6: 31C2 XOR EDX, EAX
; 0D8: 8BC2 MOV EAX, EDX
; 0DA: C1E00F SHL EAX, 15
; 0DD: 250000C6EF AND EAX, 4022730752
; 0E2: 31C2 XOR EDX, EAX
; 0E4: 8BC2 MOV EAX, EDX
; 0E6: C1E812 SHR EAX, 18
; 0E9: 31C2 XOR EDX, EAX
; 0EB: B936000000 MOV ECX, 54
; 0F0: 8BC2 MOV EAX, EDX
; 0F2: F7E1 MUL EAX, ECX
; 0F4: 8B051C60F123 MOV EAX, [#x23F1601C] ; "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjklmopqrst"
; 0FA: 8B449001 MOV EAX, [EAX+EDX*4+1]
; 0FE: 8B4DF8 MOV ECX, [EBP-8]
; 101: 89440E01 MOV [ESI+ECX+1], EAX
; 105: 8B5DF8 MOV EBX, [EBP-8]
; 108: 83C304 ADD EBX, 4
; 10B: 895DF8 MOV [EBP-8], EBX
; 10E: L5: 397DF8 CMP [EBP-8], EDI
; 111: 7C84 JL L3
; 113: 8BD6 MOV EDX, ESI
; 115: 8BE5 MOV ESP, EBP
; 117: F8 CLC
; 118: 5D POP EBP
; 119: C3 RET
NIL
I could probably optimize this more, but why? It's already fast enough, and premature optimization is stupid. When I need speed, I just run a profiler and improve the code in a few functions that take most of the time, while leaving the rest as it is. This can substantially improve the whole program's speed(unless it's something that has the code paths very uniformly distributed) and is much smarter than prematurely optimizing everything.
I M LARNIN TO SCEME (define all "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
(define len (string-length all))
(define (jib x)
(define (jab n cs)
(if (= n 0)
cs
(jab (- n 1) (cons (string-ref all (random len)) cs))))
(jab (* x 100) '()))
(list->string (jiv 100000))
takes about 550ms in Ikarus (while the exact same thing, with all defined as a list of chars and using list-ref runs around 2000ms. Wtf.)
Name:
Anonymous2010-01-12 19:03
>>16
In general, you should use higher-order functions like foldl and foldr instead of writing out the recursion. Various SRFIs provide these facilities for other data types (strings,vectors...) and you should use them. (while the exact same thing, with all defined as a list of chars and using list-ref runs around 2000ms. Wtf.)
list-ref is O(n), whereas any sane implementation of string-ref is O(1).
My scheme solution (mzscheme, but your scheme probably provides an implementation of SRFI 13 for string-tabulate)
I meant to say this in my post, but can someone check the time on a "modern computer", the one I'm currently sitting at is 5 years old and has a whopping 1GB of RAM. I don't expect a significant speed up, just curious.
Name:
Anonymous2010-01-13 1:57
>>19
I got it to run in about 3.9 seconds. (time (for ((i (in-range 1 100000))) (gibberish 100)))
cpu time: 3873 real time: 3874 gc time: 16 (time (for ((i (in-range 1 100000))) (gibberish 100)))
cpu time: 3924 real time: 3935 gc time: 4 (time (for ((i (in-range 1 100000))) (gibberish 100)))
cpu time: 3912 real time: 3911 gc time: 12