Re: [racket-users] Re: Decision Tree in Racket - Performance
Re multiple return values, you can write (call-with-values (λ () (values 1 2 3)) list) Because this problem bugs me, I've also written a package adjutor that includes values->list, list->values, and for/fold/define: http://docs.racket-lang.org/adjutor/index.html -Philip On Wed, Jul 26, 2017 at 3:00 AM, Daniel Pragerwrote: > Actually, I only use multiple values because that's what for/fold returns. > > Is there a way to convert from values to a list without going through > define-values or similar? > > Dan > > > On 26 Jul. 2017 09:40, "Zelphir Kaltstahl" > wrote: > > I've come to the conclusion, that not assuming binary classification makes > no sense, since every n-class classification problem can be split into n > binary classification problems. > > When assuming classes 0 and 1, the performance increases and I get to: > > cpu time: 608 real time: 605 gc time: 68 > > For finding the best split. > > Daniel's solution makes use of multiple return values, which were new to > me. I am using a struct for this, which might be unnecessary and later > removed in favor of returning multiple values like in Daniel's solution. > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Re: Decision Tree in Racket - Performance
Hi Gustavo Nice catch on the in-list front. I keep forgetting to do this, although I usually remember to use in-range when iterating from 0 to n-1. I tend to omit in-list for convenience rather than because I'm writing generic algorithms. I wonder what the general usage patterns are like. I guess the next step is for summertime to port this code to Typed Racket and see how that performs. Dan On 26 Jul. 2017 23:17, "Gustavo Massaccesi"wrote: I read the solution of Daniel Prager and I have a few minor changes. * First I added a test that repeats `build-tree` 20 times, so the run time is approximately 1-2 seconds. This is not necessary, but times smaller than 1 second are sometimes not reliable. I'm using: ;--- (random-seed 12345) (define data2 (shuffle banknote-data)) (time (void (build-tree (take data2 274) 5 10))) (time (for ([i (in-range 20)]) (build-tree (take data2 274) 5 10))) ;--- * Second I modified the split function so it is usable in Windows and Linux. I'm using: (string-split s #rx"\r?\n") I'm almost sure this is not the best method to write portable code. Any recommendation? * The most important change is to add `in-list` everywhere, i.e. replace (for/sum ([split splits]) ...) with (for/sum ([split (in-list splits)]) ...) I'm not sure that all of them are necessary. The `for` clauses without `in-list` are nice because they are very generic and can iterate over a lot of different data types. The problem is that they create a auxiliary sequence and use the methods of the sequence to iterate, so they are slower than expected. If you use `in-list`, the `for` is expanded to code that is specific to lists and is almost as efficient as the hand coded version like (let loop ([l my-list]) ...) and sometimes better. Most of the times you can use the generic version and use the code with any data type for free, but in the spots where you need fast code remember to use in-range, in-list, in-vector, ... (For the version that uses vectors for internal representation, you should probably use in-vector. I didn't look at the code.) Before this change a typical run time of the test is cpu time: 157 real time: 165 gc time: 0 cpu time: 3390 real time: 3393 gc time: 63 (20 times) After this change a typical run time of the test is cpu time: 62 real time: 61 gc time: 0 cpu time: 1266 real time: 1277 gc time: 62 (20 times) Gustavo PS: I made a PR with these changes in github. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: query-exec SQLite3 multiple statements
I tried query-exec on those SQL strings you posted on gist on my local copy of Racket 6.8 with an in-memory SQLite3 db and it worked fine. I'm not sure what's causing your issue. What version of Racket and SQLite3 are you running on your machine? Is it Windows, Linux, or Mac OSX? > https://gist.githubusercontent.com/abramsba/54de32406917e5fb0c480d9c214c3b08/raw/e7c0001ba19d211e856a4458316b391e77d0e530/query.sql > > https://sqliteonline.com/#fiddle-5978e22b51dfap6hj5lcvher > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Correctly executing a source file from embedded Racket
On Wednesday, July 26, 2017 at 11:09:48 AM UTC-4, Matthew Flatt wrote: > At Wed, 26 Jul 2017 07:54:32 -0700 (PDT), Thomas Dickerson wrote: > > One more thing: in terms of repeatedly executing scripts, does it make > > sense > > to set up and tear down the interpreter every time? Or just swap in a fresh > > namespace? > > Between those two options, a fresh namespace is almost certainly > better. Thanks. > Depending on how much you need to reset, you might be even better off > with `dynamic-rerequire` from `racket/rerequire`. Interesting. When would a rerequire be necessary, over a require? `dynamic-require` documentation says "Dynamically instantiates the module specified by mod in the current namespace’s registry at the namespace’s base phase, if it is not yet instantiated." Is a module instantiation local to the current namespace? If so, it sounds like wiping the namespace is sufficient. On Wednesday, July 26, 2017 at 12:27:09 PM UTC-4, Shu-Hung You wrote: > Hi Thomas, > > I tried following Matthew's suggestions to attach my-lang and use > dynamic-require. Turns out that works pretty well! And then there's > even no need to setup collection path since everything loads from > compiled byte-code. > https://gist.github.com/shhyou/aa2adaf7e1b7d548783cee352c3230a9 > > The code is basically calling (dynamic-require `(file ,argv-1) #f) to > run the external script. At line 35, the code builds (list 'file > argv-1) and at line 41 the code dynamic-requires the script. > > /* custom_dsl.cpp > > $ raco ctool --cgc --c-mods base.c ++lib racket/base ++lib > racket/base/lang/reader ++lib racket/runtime-config ++lib my-lang > ++lib my-lang/lang/reader > > $ g++ -framework Foundation -I/racket/include > -L/racket/src/build/racket > -L/racket/src/build/rktio custom_dsl.cpp -o > custom_dsl -lracket -lmzgc -lrktio -liconv > > $ ./custom_dsl ./a-module.rkt > > */ > #include > #include > > #include "base.c" > > static int run(Scheme_Env *e, int argc, char *argv[]) > { > Scheme_Object *curout; > int i; > Scheme_Thread *th; > mz_jmp_buf * volatile save, fresh; > > /* Declare embedded modules in "base.c": */ > declare_modules(e); > scheme_namespace_require(scheme_intern_symbol("my-lang")); > > curout = scheme_get_param(scheme_current_config(), > MZCONFIG_OUTPUT_PORT); > > th = scheme_get_current_thread(); > > save = th->error_buf; > th->error_buf = > if (scheme_setjmp(*th->error_buf)) { > th->error_buf = save; > return -1; /* There was an error */ > } else { > std::cout << "Trying to load file from \"" << argv[1] << "\"\n"; > Scheme_Object *custom_dsl_path[2]; > custom_dsl_path[0] = scheme_make_pair( >scheme_intern_symbol("file"), >scheme_make_pair( > scheme_make_utf8_string(argv[1]), > scheme_make_null())); > custom_dsl_path[1] = scheme_make_false(); > Scheme_Object *custom_dsl = scheme_dynamic_require(2, custom_dsl_path); > th->error_buf = save; > } > return 0; > } Thanks for the continued help with this! I found that once I switched to using `dynamic-require` I didn't even need the initial `scheme_namespace_require` The core of my script execution code now looks like this: | ret = boost::none; | Scheme_Object *drArgs[2] = {scheme_make_path(filename), resultSym_}; | Scheme_Object *loadResult = scheme_dynamic_require(2, drArgs); | if(SCHEME_CPTRP(loadResult)){ | Scheme_Object *resT = SCHEME_CPTR_TYPE(loadResult); | if(acceptedTypeTag_ == resT){ | ret = (AcceptedType*)SCHEME_CPTR_VAL(loadResult); | } else { | std::cerr << "Wrong type-tag received" << std::endl; | Scheme_Object *curout = scheme_get_param(scheme_current_config(), MZCONFIG_ERROR_PORT); | std::cerr << "Got: "; | scheme_display(resT, curout); | scheme_display(scheme_make_char('\n'), curout); | std::cerr << "Wanted: "; | scheme_display(acceptedTypeTag_, curout); | scheme_display(scheme_make_char('\n'), curout); | } | } else { | std::cerr << "Result was not a cptr" << std::endl; | } I'm now working to understand the exception handling mechanism (reading through https://docs.racket-lang.org/inside/exceptions.html and the example code). The documentation appears to be mostly centered on what to do if your C code is being called from Racket (rather than vice-versa). Looking at this code specifically: | mz_jmp_buf * volatile save, fresh; | save = scheme_current_thread->error_buf; |
[racket-users] Re: query-exec SQLite3 multiple statements
On Wed, 26 Jul 2017 11:45:25 -0700 (PDT), cmonbr...@gmail.com wrote: >First the create table is called and afterwards I execute each insert >statement. This is what displayln shows as output for sql-create: > >https://gist.githubusercontent.com/abramsba/54de32406917e5fb0c480d9c214c3b08/raw/e7c0001ba19d211e856a4458316b391e77d0e530/query.sql OMG!!! Does the term "normalization" ring a bell? >I've trimmed the string before calling query-exec but it still doesn't work. Have you tried removing the terminating semi-colon? The db query functions accept only one statement at a time and so the statements do not need to be terminated as if typed at a console. George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: query-exec SQLite3 multiple statements
On Wednesday, July 26, 2017 at 7:02:42 PM UTC+2, Alexander McLin wrote: > One more thing for you to check, make sure there's no trailing whitespace > after the end of your statement's terminating semi-colon, that will also > trigger the `multiple statements given` error. That bug has been also fixed > in the current repository. Sorry, I sent an e-mail to you individually by mistake. First the create table is called and afterwards I execute each insert statement. This is what displayln shows as output for sql-create: https://gist.githubusercontent.com/abramsba/54de32406917e5fb0c480d9c214c3b08/raw/e7c0001ba19d211e856a4458316b391e77d0e530/query.sql https://sqliteonline.com/#fiddle-5978e22b51dfap6hj5lcvher The output sql statement file also can be read in perfectly fine using .read 'filename.sql' or sqlite3 database.db < filename.sql I've trimmed the string before calling query-exec but it still doesn't work. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: query-exec SQLite3 multiple statements
One more thing for you to check, make sure there's no trailing whitespace after the end of your statement's terminating semi-colon, that will also trigger the `multiple statements given` error. That bug has been also fixed in the current repository. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: query-exec SQLite3 multiple statements
It appears you're giving to `query-exec` a string consisting of two statements; the create table and insert into statements. `query-exec` only supports executing one statement at a time. If you break your two statements up into two strings and call `query-exec` on each one, it should work. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Correctly executing a source file from embedded Racket
Hi Thomas, I tried following Matthew's suggestions to attach my-lang and use dynamic-require. Turns out that works pretty well! And then there's even no need to setup collection path since everything loads from compiled byte-code. https://gist.github.com/shhyou/aa2adaf7e1b7d548783cee352c3230a9 The code is basically calling (dynamic-require `(file ,argv-1) #f) to run the external script. At line 35, the code builds (list 'file argv-1) and at line 41 the code dynamic-requires the script. /* custom_dsl.cpp $ raco ctool --cgc --c-mods base.c ++lib racket/base ++lib racket/base/lang/reader ++lib racket/runtime-config ++lib my-lang ++lib my-lang/lang/reader $ g++ -framework Foundation -I/racket/include -L/racket/src/build/racket -L/racket/src/build/rktio custom_dsl.cpp -o custom_dsl -lracket -lmzgc -lrktio -liconv $ ./custom_dsl ./a-module.rkt */ #include #include #include "base.c" static int run(Scheme_Env *e, int argc, char *argv[]) { Scheme_Object *curout; int i; Scheme_Thread *th; mz_jmp_buf * volatile save, fresh; /* Declare embedded modules in "base.c": */ declare_modules(e); scheme_namespace_require(scheme_intern_symbol("my-lang")); curout = scheme_get_param(scheme_current_config(), MZCONFIG_OUTPUT_PORT); th = scheme_get_current_thread(); save = th->error_buf; th->error_buf = if (scheme_setjmp(*th->error_buf)) { th->error_buf = save; return -1; /* There was an error */ } else { std::cout << "Trying to load file from \"" << argv[1] << "\"\n"; Scheme_Object *custom_dsl_path[2]; custom_dsl_path[0] = scheme_make_pair( scheme_intern_symbol("file"), scheme_make_pair( scheme_make_utf8_string(argv[1]), scheme_make_null())); custom_dsl_path[1] = scheme_make_false(); Scheme_Object *custom_dsl = scheme_dynamic_require(2, custom_dsl_path); th->error_buf = save; } return 0; } int main(int argc, char **argv) { std::cout << "In cpp main\n"; return scheme_main_setup(1, run, argc, argv); } ;; a-module #lang my-lang some 'DSL that turns everything into "quotes" Cheers, Shu-Hung On Wed, Jul 26, 2017 at 10:09 AM, Matthew Flattwrote: > At Wed, 26 Jul 2017 07:54:32 -0700 (PDT), Thomas Dickerson wrote: >> One more thing: in terms of repeatedly executing scripts, does it make sense >> to set up and tear down the interpreter every time? Or just swap in a fresh >> namespace? > > Between those two options, a fresh namespace is almost certainly > better. > > Depending on how much you need to reset, you might be even better off > with `dynamic-rerequire` from `racket/rerequire`. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Correctly executing a source file from embedded Racket
At Wed, 26 Jul 2017 07:54:32 -0700 (PDT), Thomas Dickerson wrote: > One more thing: in terms of repeatedly executing scripts, does it make sense > to set up and tear down the interpreter every time? Or just swap in a fresh > namespace? Between those two options, a fresh namespace is almost certainly better. Depending on how much you need to reset, you might be even better off with `dynamic-rerequire` from `racket/rerequire`. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Correctly executing a source file from embedded Racket
Thanks for the help, a couple more quick questions: On Wednesday, July 26, 2017 at 9:15:12 AM UTC-4, Matthew Flatt wrote: > You don't have to populate the top-level environment with > `racket/base`. You could instead use > > scheme_namespace_require(scheme_intern_symbol("my-lang")) > > where "my-lang" is your language's main module to populate the > environment from there. Still, this isn't really the right direction. I actually tried this without much success, but I might still have been missing something. > Overall, I think you want to `scheme_dynamic_require` instead of > `scheme_load`, just as Shu-Hung suggests. Using > `scheme_dynamic_require` corresponds to what `racket` does where you > provide it a file on the command line, and it avoids the top-level > environment and `load`. Just tried this, and it worked great, thanks! I was having a little trouble getting the `scheme_eval` variant that constructed a `dynamic-require` form manually to work correctly, so knowing about `scheme_dynamic_require` is helpful. > I can see how the "Inside Racket" example lead you astray by showing a > traditional REPL, where `eval` and `load` come into play, and I'll look > at ways to improve the docs. But if your goal is to run modules, then > you can avoid all that trouble. Thanks! One more thing: in terms of repeatedly executing scripts, does it make sense to set up and tear down the interpreter every time? Or just swap in a fresh namespace? -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: query-exec SQLite3 multiple statements
I came across this post earlier. Does it possibly truncate the amount of characters that was passed to it? My statements don't have syntax errors, I can copy and paste them into the SQL console without a problem. Seeing as I'm looking at somewhere close to around 80.000 records I'd rather automate it. I've tested with python to make sure and it works fine there. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Re: Decision Tree in Racket - Performance
I read the solution of Daniel Prager and I have a few minor changes. * First I added a test that repeats `build-tree` 20 times, so the run time is approximately 1-2 seconds. This is not necessary, but times smaller than 1 second are sometimes not reliable. I'm using: ;--- (random-seed 12345) (define data2 (shuffle banknote-data)) (time (void (build-tree (take data2 274) 5 10))) (time (for ([i (in-range 20)]) (build-tree (take data2 274) 5 10))) ;--- * Second I modified the split function so it is usable in Windows and Linux. I'm using: (string-split s #rx"\r?\n") I'm almost sure this is not the best method to write portable code. Any recommendation? * The most important change is to add `in-list` everywhere, i.e. replace (for/sum ([split splits]) ...) with (for/sum ([split (in-list splits)]) ...) I'm not sure that all of them are necessary. The `for` clauses without `in-list` are nice because they are very generic and can iterate over a lot of different data types. The problem is that they create a auxiliary sequence and use the methods of the sequence to iterate, so they are slower than expected. If you use `in-list`, the `for` is expanded to code that is specific to lists and is almost as efficient as the hand coded version like (let loop ([l my-list]) ...) and sometimes better. Most of the times you can use the generic version and use the code with any data type for free, but in the spots where you need fast code remember to use in-range, in-list, in-vector, ... (For the version that uses vectors for internal representation, you should probably use in-vector. I didn't look at the code.) Before this change a typical run time of the test is cpu time: 157 real time: 165 gc time: 0 cpu time: 3390 real time: 3393 gc time: 63 (20 times) After this change a typical run time of the test is cpu time: 62 real time: 61 gc time: 0 cpu time: 1266 real time: 1277 gc time: 62 (20 times) Gustavo PS: I made a PR with these changes in github. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Correctly executing a source file from embedded Racket
At Tue, 25 Jul 2017 19:08:02 -0700 (PDT), Thomas Dickerson wrote: > On Tuesday, July 25, 2017 at 5:52:45 PM UTC-4, Shu-Hung You wrote:> > > As we can see, > `scheme_namespace_require(scheme_intern_symbol("racket/base"));` > > is actually missing from your setup program. This line requires racket > > base and the usual #%app bindings. It's probably needed even if you're > > loading your own DSL -- I suspect at some point racket/base will > > install the right `load` function to make things work, and that this > > will also affect loading custom #langs. > > You appear to be correct, but it strikes me as really odd that > (a) In a language which prides itself on metaprogramming, the interpreter > namespace needs to be manually bootstrapped with a specific module. > (b) That the form the error takes is not an error with the requires/provides > in the `main.rkt` for my #lang, but as an error in a module which is using it. I think the root problem is that you're thinking of `load` as `dynamic-require`, but those are different. The `load` function, including its C wrapper `scheme_load`, loads a top-level sequence of forms in the top-level environment. For that to work, the top-level environment needs to be populated with bindings. You don't have to populate the top-level environment with `racket/base`. You could instead use scheme_namespace_require(scheme_intern_symbol("my-lang")) where "my-lang" is your language's main module to populate the environment from there. Still, this isn't really the right direction. Meanwhile, since the top-level environment was empty, the message didn't come from the inside of a module. There was no `#%top-interaction` or `module` binding in the top-level environment, so nothing in "gpsm-test.gpsm" was parsed as a module. Instead, the error was attributed to a top-level form in "gpsm-test.gpsm" that could not be given any meaning in the current top-level environment. Overall, I think you want to `scheme_dynamic_require` instead of `scheme_load`, just as Shu-Hung suggests. Using `scheme_dynamic_require` corresponds to what `racket` does where you provide it a file on the command line, and it avoids the top-level environment and `load`. I can see how the "Inside Racket" example lead you astray by showing a traditional REPL, where `eval` and `load` come into play, and I'll look at ways to improve the docs. But if your goal is to run modules, then you can avoid all that trouble. Going back to the original message on `++lib`, to add a little to Shu-Hung's reply: > I noticed some oddities when using `raco ctool`. For example, the > documentation claims that a module specified for embedding with ++lib will > embed all of its dependencies, but my #lang's reader submodule needed to be > explicitly specified with its own ++lib argument. A language implementation normally would not depend on that language's reader. If you have #lang racket 'hello (module reader racket) then the enclosing module doesn't import the `reader` submodule, so it doesn't depend on it. (If you compile and load that module, then the `reader` submodule isn't event loaded.) So, if I understand the situation you're describing, that's why the reader submodule didn't get pulled along when embedding the outer module. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: query-exec SQLite3 multiple statements
There's a problem with the sqlite interface where "multiple statements given" error is reported for any syntax error. This was fixed only recently. See previous discussion: https://groups.google.com/forum/#!searchin/racket-users/sqlite$20multiple$20statements$20given%7Csort:relevance/racket-users/s2wh-w2GF6M/Bh4A-DNKDAAJ Best Regards, Alex. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] [ANN] MessagePack implementation for Racke
On Tuesday, July 25, 2017 at 11:37:48 PM UTC+2, Lehi Toskin wrote: > One thing I'm curious about is what things can you and can you not pack? In > the README it shows bytes being packed, which seems a little obvious, but > what about (transparent) structs? Hashes? Lists? I'm very interested in this > package... for science! I am not packing bytes in the readme, I am packing an integer in hexadecimal notation so one can see easier how the integer corresponds to the packed bytes: #x1234 becomes #xCD #x12 #x34, the first byte is the type tag for unsigned 16-bit integers and the other two are the bytes of the integer. Packing means turning a Racket object into a byte sequence that can be sent to another process. The recipient might not know anything about Racket, but it still needs to be able to figure out how to put the byte sequence back together, that's why there is a type tag. In theory you can pack anything as long as the recipient knows how it was packed. Vectors and lists get packed into MessagePack arrays, hash tables into MessagePack maps. If you want to pack a custom type like a point struct '(struct point (x y))' you have a number of options. You could use the MessagePack ext type which allows you to assign a custom type tag, then you have to tell the recipient that for example the magic number 13 means point. If the struct is transparent and you can 'read' and 'write' it in Racket you could also pack the point as a string, but then you somehow have to make sure the recipient knows that the string is meant to be an object and not just some arbitrary text. I think it would be worthwhile to later add the ability to define your own packing functions so that you could then just call '(pack my-point out)'. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] [ANN] MessagePack implementation for Racke
Here is what I get from profiling the different dispatch methods in 'unpack'. First I pack a positive fixnum which is among the first few conditions. Cond: cpu time: 810 real time: 3367 gc time: 0 cpu time: 815 real time: 3428 gc time: 0 cpu time: 815 real time: 3197 gc time: 0 cpu time: 806 real time: 3045 gc time: 0 cpu time: 806 real time: 3125 gc time: 0 cpu time: 811.5 real time: 3232.4 Case: cpu time: 817 real time: 3122 gc time: 0 cpu time: 835 real time: 3544 gc time: 0 cpu time: 830 real time: 3337 gc time: 0 cpu time: 824 real time: 3216 gc time: 0 cpu time: 840 real time: 3667 gc time: 0 cpu time: 829.2 real time: 3377.2 Vector: cpu time: 844 real time: 3839 gc time: 0 cpu time: 826 real time: 3253 gc time: 0 cpu time: 835 real time: 3194 gc time: 0 cpu time: 840 real time: 3165 gc time: 0 cpu time: 838 real time: 3354 gc time: 0 cpu time: 836.6 real time: 3361.0 Next I packed a negative fixnum, which is the last condition case: Cond: cpu time: 953 real time: 3556 gc time: 0 cpu time: 940 real time: 3035 gc time: 0 cpu time: 986 real time: 4250 gc time: 2 cpu time: 946 real time: 3425 gc time: 0 cpu time: 945 real time: 3233 gc time: 0 cpu time: 954.0 real time: 3499.8 Case: cpu time: 890 real time: 2820 gc time: 0 cpu time: 896 real time: 2799 gc time: 0 cpu time: 904 real time: 2783 gc time: 2 cpu time: 884 real time: 2751 gc time: 0 cpu time: 887 real time: 2789 gc time: 0 cpu time: 892.2 real time: 2788.4 Vector: cpu time: 866 real time: 2704 gc time: 0 cpu time: 884 real time: 2981 gc time: 0 cpu time: 880 real time: 2661 gc time: 3 cpu time: 864 real time: 2647 gc time: 0 cpu time: 864 real time: 2597 gc time: 0 cpu time: 871.6 real time: 2718.0 The average is below the line for each. I tested it by unpacking an array of 2^16 items, all the values were hard-coded so there is no chance of poor macros messing things up. The dispatch vector is a vector of functions like this: (define dispatch (vector ... (lambda (in) (unpack-float 32 in)) ; #xCA ... )) The unpacking function looks like this: (define (unpack in) (define tag (read-byte in)) (time ((vector-ref dispatch tag) in))) So in conclusion it looks like the vector is the fastest when it comes to cases later down the list while the 'cond' is the fastest at first, but slowest at the end, slower than the vector at the beginning. The case averages somewhere between the two. Should I pick 'case' so I get average performance consistently, or should I pick the vector so I get the best performance in the worst case? I don't think one can predict which type of data users will most likely want to unpack on average. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: [ANN] MessagePack implementation for Racke
On Tuesday, July 25, 2017 at 11:37:48 PM UTC+2, Lehi Toskin wrote: > One thing I'm curious about is what things can you and can you not pack? In > the README it shows bytes being packed, which seems a little obvious, but > what about (transparent) structs? Hashes? Lists? I'm very interested in this > package... for science! In theory anything can be packed as long as you can agree on *how* it should be packed. For example, if you have a point '(struct point (x y))', how should that be packed? There is no "point" type in MessagePack and no direct correspondance, so you would have to tell the recipient of your data "a point looks like this: ...". You could use the MessagePack 'ext' type, it consist of an 8-bit integer as a type tag and raw binary data, so you could agree with the recipient that the tag '13' stands for point and the data is two big-endian 64-bit numbers in the order 'x' and 'y'. Or you could pack a transparent struct as a string that you can 'read' and 'write' in Racket. For hash tables there is the map type and for vectors and lists there is the array type, so those are direct 1:1 correspondences. The elements of these are themselves individually packed, so if you have a list of hash tables that structure will be preserved. I think adding the ability to define your own packing functions as additions to the library is something that's worth looking into later. Then you could define your own 'pack-point' and add it to the generic 'pack' function. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] query-exec SQLite3 multiple statements
I'm working on converting a number of CSV files into SQLite3 tables. As of now I export the SQL statements to a text file and import them afterwards. ``` (define (csv->sqlfiles) (for-each (λ (e) (let* ([csv_filepath (string-append csv_dir (path->string e))] [table_name (path->string (path-replace-extension e #""))] [sql_filepath (string-append sql_dir table_name ".sql")] [contents (file->lines csv_filepath #:mode 'text)] [columns (length (string-split (first contents) "\t"))] [sql-create (format "create table ~s ( ~a );" table_name (string-join (map (λ (e) (format "~s text" e)) (string-split (first contents) "\t")) ", "))] [sql-inserts (map (λ (e) (format "insert into ~s values ( ~a );" table_name (string-join (map (λ (e) (format "~s" e)) (regexp-split #px"\t" e)) ","))) (list-tail contents 1))] [outfile (open-output-file sql_filepath #:exists 'truncate)]) (displayln sql-create outfile) (for-each (λ (e) (let () (displayln e outfile))) sql-inserts) (close-output-port outfile))) (directory-list csv_dir))) ``` I end up with something looking like this: ``` create table "actionname-e" ( "tag" text, "id" text, "type" text, "category" text, "cat2_cnt" text, "c[0]" text, "c[1]" text, ... ); insert into "actionname-e" values ( "1", "0", "-1", "1", "1", "-2", ... ,"a,Sit/Stand\\0","a,icon.action001\\0","a,Toggle Sit/Stand. (/sit, /stand)\\0","sitstand" ); ``` If I use `.read` from sqlite than it works perfectly fine. When I try to swap the file output statements for queries though: ``` (query-exec sql sql-create) (for-each (λ (e) (let () (query-exec sql e))) sql-inserts))) ``` I assume there's a syntax issue but the error being reported is 'multiple statements'. ``` query-exec: multiple statements given given: "create table \"actionname-e\" ( \"tag\" text, \"id\" text, \"type\" text, \"category\" text, \"cat2_cnt\" text, \"c[0]\" text, \"c[1]\" text, \"c[2]\" text, \"c[3]\" text, \"c[4]\" text, \"c[5]\" text, \"c[6]\" text, \"c[7]\" text, \"c[8]\" text,... ``` I'm not sure though what exactly is going wrong because the statements in the file run perfectly fine. I assume racket formats the string in a way but I have no way to tell. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Re: Decision Tree in Racket - Performance
Actually, I only use multiple values because that's what for/fold returns. Is there a way to convert from values to a list without going through define-values or similar? Dan On 26 Jul. 2017 09:40, "Zelphir Kaltstahl"wrote: I've come to the conclusion, that not assuming binary classification makes no sense, since every n-class classification problem can be split into n binary classification problems. When assuming classes 0 and 1, the performance increases and I get to: cpu time: 608 real time: 605 gc time: 68 For finding the best split. Daniel's solution makes use of multiple return values, which were new to me. I am using a struct for this, which might be unnecessary and later removed in favor of returning multiple values like in Daniel's solution. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.