November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | Jacob Carlborg:
> What does this show, that ranges is slow in D?
It shows that D is awesome. Do you know other languages that allow you to write two programs to solve that problem as short/simple and as fast as those two? :-)
Bye,
bearophile
|
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to qznc | qznc:
>> http://rosettacode.org/wiki/Look-and-say_sequence#D
>
> The fast version is nearly functional, too. Since memory management is not considered a side effect there is only the printfs. If the printfs are wrapped into "debug", the function is pure.
In a system that allows you a more fine-graded management of effects through an algebra, memory allocation is an effect. It's easy to show D functions annotated with "pure" that aren't pure at all because of memory allocation.
Bye,
bearophile
|
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 11/15/13 7:54 AM, bearophile wrote:
> Jacob Carlborg:
>
>> What does this show, that ranges is slow in D?
>
> It shows that D is awesome. Do you know other languages that allow you
> to write two programs to solve that problem as short/simple and as fast
> as those two? :-)
>
> Bye,
> bearophile
Probably Crystal.
Here's what I was able to do in some minutes:
---
if ARGV.length != 1
puts "missing argument: n"
exit 1
end
n = ARGV[0].to_i
str = "1"
buffer = String::Buffer.new(20)
n.times do
puts str.length
str.each_chunk do |digit, count|
buffer << '0' + count
buffer << digit
end
str = buffer.to_s
buffer.clear
end
---
With n=70 it takes about 4.89s. With n=45 it takes about 0.012s.
And with Crystal you could do the second version as well, because you have access to low level stuff like pointers. And also, the language is pretty new so there's still a lot of optimizations to be done.
I also thought ranges were pretty fast because of their nature. Why are they slow in this example?
|
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 15 November 2013 at 01:59:27 UTC, bearophile wrote:
> The first program doesn't even compile with ldc2 v.2.063.2, and
Does it compile with dmd 2.063.2? (Is it a D version problem or a LDC bug?)
Regards,
Kai
|
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kai Nacke | Kai Nacke:
> Does it compile with dmd 2.063.2? (Is it a D version problem or a LDC bug?)
>
> Regards,
> Kai
If I find a ldc2 bug I show it in the right newsgroup, so don't worry. It's a matter of updates (purity) in a Phobos function.
Bye,
bearophile
|
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | Ary Borenszweig: > Here's what I was able to do in some minutes: > > --- > if ARGV.length != 1 > puts "missing argument: n" > exit 1 > end > > n = ARGV[0].to_i > str = "1" > buffer = String::Buffer.new(20) > n.times do > puts str.length > str.each_chunk do |digit, count| > buffer << '0' + count > buffer << digit > end > str = buffer.to_s > buffer.clear > end > > With n=70 it takes about 4.89s. With n=45 it takes about 0.012s. This program is much longer in number of tokens to the first D program. You can write a D program about as fast as this in about the same number of tokens. Perhaps I should add an intermediate third version that shows code that's not as extreme as the two versions there. Thank you for the implicit suggestion. > And with Crystal you could do the second version as well, because you have access to low level stuff like pointers. In Crystal do you have final switches, gotos, etc too? > And also, the language is pretty new so there's still > a lot of optimizations to be done. And LDC2 will improve in the meantime. > I also thought ranges were pretty fast because of their nature. It also matters a lot how you use them, this is normal in computer programming. > Why are they slow in this example? Just because the first example is not written for speed, I didn't even add run-time timings for it at first. And it's not that slow. Bye, bearophile |
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 15 November 2013 at 12:47:21 UTC, bearophile wrote:
> Ary Borenszweig:
>
>> Here's what I was able to do in some minutes:
>>
>> ---
>> if ARGV.length != 1
>> puts "missing argument: n"
>> exit 1
>> end
>>
>> n = ARGV[0].to_i
>> str = "1"
>> buffer = String::Buffer.new(20)
>> n.times do
>> puts str.length
>> str.each_chunk do |digit, count|
>> buffer << '0' + count
>> buffer << digit
>> end
>> str = buffer.to_s
>> buffer.clear
>> end
>>
>> With n=70 it takes about 4.89s. With n=45 it takes about 0.012s.
>
> This program is much longer in number of tokens to the first D program. You can write a D program about as fast as this in about the same number of tokens.
>
> Perhaps I should add an intermediate third version that shows code that's not as extreme as the two versions there. Thank you for the implicit suggestion.
>
>
>> And with Crystal you could do the second version as well, because you have access to low level stuff like pointers.
>
> In Crystal do you have final switches, gotos, etc too?
>
>
>> And also, the language is pretty new so there's still
>> a lot of optimizations to be done.
>
> And LDC2 will improve in the meantime.
>
>
>> I also thought ranges were pretty fast because of their nature.
>
> It also matters a lot how you use them, this is normal in computer programming.
>
>
>> Why are they slow in this example?
>
> Just because the first example is not written for speed, I didn't even add run-time timings for it at first. And it's not that slow.
>
> Bye,
> bearophile
Slightly OT: Why do languages like Ruby (and now Crystal) have to state the obvious in an awkward way?
(2...max).each do
Of course you _do_ _each one_ from 2 to max. Is it to make it more "human"? If anything, human languages and thinking get rid of the superfluous (i.e. the obvious). Just like
x = x + 1 (Pythronizing)
x++; (obvious, concise, all you need).
Buy one, get one free.
(= If you buy one (of these), you will get one (another one of these) for free.)
Sorry that was just a rant-om comment :)
|
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 11/15/13 9:47 AM, bearophile wrote: > Ary Borenszweig: > >> Here's what I was able to do in some minutes: >> >> --- >> if ARGV.length != 1 >> puts "missing argument: n" >> exit 1 >> end >> >> n = ARGV[0].to_i >> str = "1" >> buffer = String::Buffer.new(20) >> n.times do >> puts str.length >> str.each_chunk do |digit, count| >> buffer << '0' + count >> buffer << digit >> end >> str = buffer.to_s >> buffer.clear >> end >> >> With n=70 it takes about 4.89s. With n=45 it takes about 0.012s. > > This program is much longer in number of tokens to the first D program. > You can write a D program about as fast as this in about the same number > of tokens. No. I just counted the tokens and D has more tokens: http://pastebin.com/XZFf8dsj It's even longer if I keep all the programs arguments checking (ARGV). If I remove that, the program has 45 tokens. The D version has 81 tokens. And without the imports, D still has 68 tokens. (well, I didn't count newlines as tokens, so maybe that's unfair because newlines in Crystal are significant) Yes, it's not as functional as D. But only because the language is still young. > > Perhaps I should add an intermediate third version that shows code > that's not as extreme as the two versions there. Thank you for the > implicit suggestion. > > >> And with Crystal you could do the second version as well, because you >> have access to low level stuff like pointers. > > In Crystal do you have final switches, gotos, etc too? No. In this D will always be better, if you really want your program to have gotos. >> And also, the language is pretty new so there's still >> a lot of optimizations to be done. > > And LDC2 will improve in the meantime. And so LLVM, which is what Crystal uses as a backend. > > >> I also thought ranges were pretty fast because of their nature. > > It also matters a lot how you use them, this is normal in computer > programming. But I thought ranges were meant to be fast. No allocations and all of that. In fact, I was kind of sad that Crystal doesn't have a similar concept so it could never get as fast as D ranges. But if D ranges are not fast, what's the point of having them and making everyone use them? > > >> Why are they slow in this example? > > Just because the first example is not written for speed, I didn't even > add run-time timings for it at first. And it's not that slow. Ah, I thought you did. So I misunderstood your timings. Sorry. > > Bye, > bearophile |
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On 2013-11-15 14:07, Chris wrote: > Slightly OT: Why do languages like Ruby (and now Crystal) have to state > the obvious in an awkward way? > > (2...max).each do You can do this as well in Ruby: for e in 2 ... max end But Ruby follows the philosophy that everything is an object. So you invoke the "each" method on the range object. > Of course you _do_ _each one_ from 2 to max. Is it to make it more > "human"? If anything, human languages and thinking get rid of the > superfluous (i.e. the obvious). Just like > > x = x + 1 (Pythronizing) > x++; (obvious, concise, all you need). This middle ground is possible in Ruby: x += 1 -- /Jacob Carlborg |
November 15, 2013 Re: Look and think good things about D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On 11/15/13 10:07 AM, Chris wrote:
> On Friday, 15 November 2013 at 12:47:21 UTC, bearophile wrote:
>> Ary Borenszweig:
>>
>>> Here's what I was able to do in some minutes:
>>>
>>> ---
>>> if ARGV.length != 1
>>> puts "missing argument: n"
>>> exit 1
>>> end
>>>
>>> n = ARGV[0].to_i
>>> str = "1"
>>> buffer = String::Buffer.new(20)
>>> n.times do
>>> puts str.length
>>> str.each_chunk do |digit, count|
>>> buffer << '0' + count
>>> buffer << digit
>>> end
>>> str = buffer.to_s
>>> buffer.clear
>>> end
>>>
>>> With n=70 it takes about 4.89s. With n=45 it takes about 0.012s.
>>
>> This program is much longer in number of tokens to the first D
>> program. You can write a D program about as fast as this in about the
>> same number of tokens.
>>
>> Perhaps I should add an intermediate third version that shows code
>> that's not as extreme as the two versions there. Thank you for the
>> implicit suggestion.
>>
>>
>>> And with Crystal you could do the second version as well, because you
>>> have access to low level stuff like pointers.
>>
>> In Crystal do you have final switches, gotos, etc too?
>>
>>
>>> And also, the language is pretty new so there's still
>>> a lot of optimizations to be done.
>>
>> And LDC2 will improve in the meantime.
>>
>>
>>> I also thought ranges were pretty fast because of their nature.
>>
>> It also matters a lot how you use them, this is normal in computer
>> programming.
>>
>>
>>> Why are they slow in this example?
>>
>> Just because the first example is not written for speed, I didn't even
>> add run-time timings for it at first. And it's not that slow.
>>
>> Bye,
>> bearophile
>
> Slightly OT: Why do languages like Ruby (and now Crystal) have to state
> the obvious in an awkward way?
>
> (2...max).each do
>
> Of course you _do_ _each one_ from 2 to max. Is it to make it more
> "human"?
Absolutely. You are a human and you spend a lot of time reading code. The more human the code looks to you, the better, I think, as long as it doesn't become too long or too annoying to read, like:
for every number between 2 and max do
...
end
:-P
|
Copyright © 1999-2021 by the D Language Foundation