Зачем нужны поля в .Net?
От: snaphold  
Дата: 23.09.09 05:50
Оценка: +1 :)
Скажите зачем нужны поля, если всё можно сделать с помощью свойств.
Я рассматриваю только свойства имеющие оба акксесора.
Re: Зачем нужны поля в .Net?
От: Aen Sidhe Россия Просто блог
Дата: 23.09.09 05:56
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>Я рассматриваю только свойства имеющие оба акксесора.

Наверно затем, чтобы хранить инфу, которую "можно сделать с помощью свойств".
С уважением, Анатолий Попов.
ICQ: 995-908
Re[2]: Зачем нужны поля в .Net?
От: snaphold  
Дата: 23.09.09 06:02
Оценка:
Здравствуйте, Aen Sidhe, Вы писали:

AS>Здравствуйте, snaphold, Вы писали:


S>>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>>Я рассматриваю только свойства имеющие оба акксесора.

AS>Наверно затем, чтобы хранить инфу, которую "можно сделать с помощью свойств".


а зачем лишние сущности, если я могу записывать, считывать и хранить всё это с помощью свойств?
Re: Зачем нужны поля в .Net?
От: Pavel Dvorkin Россия  
Дата: 23.09.09 06:19
Оценка: 1 (1) +2 :))) :))) :)))
Здравствуйте, snaphold, Вы писали:

S>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>Я рассматриваю только свойства имеющие оба акксесора.

М-да... Судя по всему, следующий вопрос (через пару лет) будет — зачем нужны циклы, если есть LinQ
With best regards
Pavel Dvorkin
Re: Зачем нужны поля в .Net?
От: Lexxpin  
Дата: 23.09.09 06:27
Оценка: +1
Здравствуйте, snaphold, Вы писали:

S>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>Я рассматриваю только свойства имеющие оба акксесора.

Как реализуешь паттерн OnPropertyChanged без полей?
Re[3]: Зачем нужны поля в .Net?
От: MxKazan Португалия  
Дата: 23.09.09 06:28
Оценка: +1
Здравствуйте, snaphold, Вы писали:

S>а зачем лишние сущности, если я могу записывать, считывать и хранить всё это с помощью свойств?

Поля как раз и применяются там, где свойства, а точнее его аксессоры — лишние сущности.
Re[2]: Зачем нужны поля в .Net?
От: MxKazan Португалия  
Дата: 23.09.09 06:42
Оценка: :)))
Здравствуйте, Lexxpin, Вы писали:

L>Как реализуешь паттерн OnPropertyChanged без полей?

Не, ну если захотеть, отдельными приватными свойствами
class Data : INotifyPropertyChanged
{
    private int value
    {
        get;
        set;
    }

    public int Value
    {
        get
        {
            return this.value;
        }
        set
        {
            if (this.value != value)
            {
                this.value = value;
                this.OnPropertyChanged("Value");
            }
        }
    }
    ...
}
Re[4]: Зачем нужны поля в .Net?
От: snaphold  
Дата: 23.09.09 06:42
Оценка:
Здравствуйте, MxKazan, Вы писали:

MK>Здравствуйте, snaphold, Вы писали:


S>>а зачем лишние сущности, если я могу записывать, считывать и хранить всё это с помощью свойств?

MK>Поля как раз и применяются там, где свойства, а точнее его аксессоры — лишние сущности.

Пример в студию
Re: Зачем нужны поля в .Net?
От: Lexxpin  
Дата: 23.09.09 06:50
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>Я рассматриваю только свойства имеющие оба акксесора.

А вы в курсе что такое свойство с точки зрения CLR?
Re[5]: Зачем нужны поля в .Net?
От: MxKazan Португалия  
Дата: 23.09.09 06:55
Оценка: +1
Здравствуйте, snaphold, Вы писали:

S>Пример в студию

Тут не пример нужен, а просто рассуждения. Что такое свойство? Это по сути два метода аксессора set и get. Поэтому любое обращение к свойству — это вызов метода (не будем принимать во внимание оптимизацию). Спрашивается, зачем мне вызывать метод для простого присваивания?

И потом, поля нужны для interop'а.
Советую также посмотреть этот
Автор: Пельмешко
Дата: 14.03.09
пост, на тему сравнения "простых" свойств и readonly полей.
Re: Зачем нужны поля в .Net?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 23.09.09 07:30
Оценка: +1 :)
Здравствуйте, snaphold, Вы писали:

S>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>Я рассматриваю только свойства имеющие оба акксесора.

В основном по историческим причинам.
Ну, еще поле можно передать как ref/out параметр.
А в поле, типом которого является value-тип, легко можно поменять отдельное поле этого value-типа (но это можно было бы эмулировать и для свойств).
Re[6]: Зачем нужны поля в .Net?
От: Pavel Dvorkin Россия  
Дата: 23.09.09 09:07
Оценка:
Здравствуйте, MxKazan, Вы писали:

MK>Здравствуйте, snaphold, Вы писали:


S>>Пример в студию

MK>Тут не пример нужен, а просто рассуждения. Что такое свойство? Это по сути два метода аксессора set и get. Поэтому любое обращение к свойству — это вызов метода (не будем принимать во внимание оптимизацию). Спрашивается, зачем мне вызывать метод для простого присваивания?

А может, проще без рассуждений ? Выделено мной — PD

Auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors. When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field can only be accessed through the property's get and set accessors

А когда вы его declare не так как в этом example, то вам придется это поле создать вручную и в свойстве set в него что-то занести.
With best regards
Pavel Dvorkin
Re[2]: Зачем нужны поля в .Net?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 23.09.09 09:24
Оценка:
Здравствуйте, Aen Sidhe, Вы писали:

S>>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>>Я рассматриваю только свойства имеющие оба акксесора.

AS>Наверно затем, чтобы хранить инфу, которую "можно сделать с помощью свойств".


В языке вполне может не быть различий между полями, и тем, что в C# называется auto properties.
Например, поля в Scala — это совсем не то, что в C# называется полями. Например, они могут быть виртуальными, или принадлежать trait-у.

Просто C# — это довольно низкоуровневый язык (по крайней мере, он был таким в первых версиях), поэтому для него может иметь смысл говорить о физическом расположении данных в памяти.
Re[2]: Зачем нужны поля в .Net?
От: 9kpm66  
Дата: 23.09.09 10:45
Оценка:
Здравствуйте, Lexxpin, Вы писали:

L>А вы в курсе что такое свойство с точки зрения CLR?


А вы в курсе что такое CLR с точки зрения линуксоида?
Re[3]: Зачем нужны поля в .Net?
От: MozgC США http://nightcoder.livejournal.com
Дата: 23.09.09 10:48
Оценка:
Здравствуйте, 9kpm66, Вы писали:

9>А вы в курсе что такое CLR с точки зрения линуксоида?


Это Вы к чему вообще?
Re[7]: Зачем нужны поля в .Net?
От: MxKazan Португалия  
Дата: 23.09.09 10:52
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А может, проще без рассуждений ? Выделено мной — PD

Обобщил просто.

PD>Auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors. When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field can only be accessed through the property's get and set accessors


PD>А когда вы его declare не так как в этом example, то вам придется это поле создать вручную и в свойстве set в него что-то занести.

И тем не менее, я привел пример, когда поля в классе нет, если абстрагироваться от того, что генерит компилятор. Это поведение (генерацию поля) в теории можно легко изменить, если из языка устранить само понятие поля. Ну т.е. сделать что-то вроде свойств хранилищ (бывшие поля) и свойств с аксессорами
Re[5]: Зачем нужны поля в .Net?
От: Vladek Россия Github
Дата: 23.09.09 12:56
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Здравствуйте, MxKazan, Вы писали:


MK>>Здравствуйте, snaphold, Вы писали:


S>>>а зачем лишние сущности, если я могу записывать, считывать и хранить всё это с помощью свойств?

MK>>Поля как раз и применяются там, где свойства, а точнее его аксессоры — лишние сущности.

S>Пример в студию


Любой объект с неизменным состоянием (immutable object).
One bad programmer can easily create two new jobs a year.
Re: Зачем нужны поля в .Net?
От: Vladek Россия Github
Дата: 23.09.09 12:56
Оценка: 1 (1)
Здравствуйте, snaphold, Вы писали:

S>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>Я рассматриваю только свойства имеющие оба акксесора.

Хранить состояние объекта. Свойства отвечают за поведение, а не состояние.
Developers, developers, developers, developers, developers, developers, developers... © Steve Ballmer
Re[2]: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.09.09 14:32
Оценка: +1 :))
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>М-да... Судя по всему, следующий вопрос (через пару лет) будет — зачем нужны циклы, если есть LinQ


Этот вопрос был поставлен уже давно. Только звучал он немного по другому — "Зачем нужны циклы если есть рекурсивные функции, функции высшего порядка и макросы?".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.09.09 14:43
Оценка: +2
Здравствуйте, snaphold, Вы писали:

S>Скажите зачем нужны поля, если всё можно сделать с помощью свойств.

S>Я рассматриваю только свойства имеющие оба акксесора.

Вопрос не так глуп как может показаться некоторым.
Только вопрос сформулирован не точно.

Физически поля несомненно нужны, так как только они могут хранить данные. Свойства — это не более чем синтаксический сахар для функций доступа.

Однако если рассматривать язык программирования, то свойства и поля действительно дублируют функциональность.

Я как-то уже думал на эту тему и пришел к выводу, что в языке можно было бы избавиться от лишней абстракции. Поля можно было бы переставлять как свойства с двумя публичными эксесорами. Это упростило бы язык и сделало бы более легким использование рефлексии (поля попросту можно было бы игнорировать во многих случаях).

Кроме того лишними элементами является ref- и out-параметры. Вместо них лучше было бы ввести в рантайм поддержку таких сущностей как кортежи (наборы разнотипных не именованных значений) и записи (наборы именованных разнотипных значений) которые можно было бы описывать прямо по месту (при декларации типа). Кортежи можно эмулировать и сейчас, а вот с записями все печально. Без поддержки рантайма качественно их не реализовать.

Вообще, в современных виртуальных машинах вроде дотнета и явы сделано много ошибок. В основном их причиной является то, что авторы этих рантаймов были знакомы только с ООП и КООП и не думали о поддержке ФП и МП.

На мой взгляд было бы интересно обсудить какие просчеты были сделаны в виртуальных машинах и языках. И то как должны выглядеть более совершенные ВМ и ЯП.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.09.09 14:45
Оценка:
Здравствуйте, 9kpm66, Вы писали:

L>>А вы в курсе что такое свойство с точки зрения CLR?


9>А вы в курсе что такое CLR с точки зрения линуксоида?


Это зависит от определения данного термина. Если рассматривать "линуксойда" как недалекого фаната, то наверно что-то очень неприятное и плохое. Если это образованный и рассудительный человек, то термин будет означать тоже самое, что и для остальных — ядро виртуальной машины. Тоже самое что ява-ратнайм.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.09.09 14:46
Оценка:
Здравствуйте, nikov, Вы писали:

N>А в поле, типом которого является value-тип, легко можно поменять отдельное поле этого value-типа (но это можно было бы эмулировать и для свойств).


На мой взгляд, даже не "можно", а "нужно".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Зачем нужны поля в .Net?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 23.09.09 15:06
Оценка:
Здравствуйте, VladD2, Вы писали:

N>>А в поле, типом которого является value-тип, легко можно поменять отдельное поле этого value-типа (но это можно было бы эмулировать и для свойств).


VD>На мой взгляд, даже не "можно", а "нужно".


Очень может быть. Кстати, как в Nemerle с этим?
Re[4]: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.09.09 16:12
Оценка:
Здравствуйте, nikov, Вы писали:

N>>>А в поле, типом которого является value-тип, легко можно поменять отдельное поле этого value-типа (но это можно было бы эмулировать и для свойств).


VD>>На мой взгляд, даже не "можно", а "нужно".


N>Очень может быть. Кстати, как в Nemerle с этим?


Как ты понимаешь — это проблема не языка, а платформы. В прочем, можно подумать над тем, чтобы выявлять такие случае и автоматически переписывать код.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Зачем нужны поля в .Net?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 23.09.09 16:16
Оценка:
Здравствуйте, VladD2, Вы писали:

N>>>>А в поле, типом которого является value-тип, легко можно поменять отдельное поле этого value-типа (но это можно было бы эмулировать и для свойств).

VD>>>На мой взгляд, даже не "можно", а "нужно".
N>>Очень может быть. Кстати, как в Nemerle с этим?

VD>Как ты понимаешь — это проблема не языка, а платформы. В прочем, можно подумать над тем, чтобы выявлять такие случае и автоматически переписывать код.


Честно говоря, я не понимаю, как платформа может догадаться, что изменение в значении, возвращенном геттером свойства, надо как-то транслировать обратно в то место, откуда его взяли, если компилятор явно не сгенерирует соответствующий код. В C# выбрано простое решение: выдавать ошибку компиляции в таких случаях. Подозреваю, что сейчас Nemerle не выдает ошибку, а молча игнорирует изменения.
Re[3]: Зачем нужны поля в .Net?
От: EvilChild Ниоткуда  
Дата: 23.09.09 16:20
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Этот вопрос был поставлен уже давно. Только звучал он немного по другому — "Зачем нужны циклы если есть рекурсивные функции, функции высшего порядка и макросы?".


А макросы сюда каким боком относятся? Первых 2х недостаточно?
now playing: Massive Attack — Bulletproof Love (feat. Guy Garvey) (Christoff Berg Remix)
Re[6]: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.09.09 16:47
Оценка:
Здравствуйте, nikov, Вы писали:

N>Честно говоря, я не понимаю, как платформа может догадаться, что изменение в значении, возвращенном геттером свойства, надо как-то транслировать обратно в то место, откуда его взяли, если компилятор явно не сгенерирует соответствующий код. В C# выбрано простое решение: выдавать ошибку компиляции в таких случаях.


Есть четкий паттерн:
1. Взяли значение из свойства.
2. Изменили это значение.
3. Никуда не положили.

N>Подозреваю, что сейчас Nemerle не выдает ошибку, а молча игнорирует изменения.


Ну, как сказать. Вот такой код:

[Record]
struct A
{
  public mutable X : int;
}

[Record]
class B
{
  public Prop : A { get; set; }
}

def b = B(A(123));
b.Prop.X = 654;
System.Console.WriteLine(b.Prop.X);

Выдает:
x.n:14:1:14:15: error: this expression is not a proper lvalue: cannot load value type address


Правда, нашелся баг. Вот такой вариант:
[Record]
struct A
{
  public mutable X : int;
}

[Record]
class B
{
  public Prop : A { get; set; }
}

def b = B(A(123));
b.Prop.X++;
System.Console.WriteLine(b.Prop.X);

Успешно компилируется, но приводит к выдачи весьма странного рантайм-исключения:
====WARNING====
You have probably encountered known bug VSW:137474, which fires
when System.EnterpriseServices.Thunk.Proxy::LazyRegister is jitted.
The bug often shows up in tests under ManagedServices\Interop.
VSW:137474 has been fixed, but the fix has not yet been propagated
to Lab21S. Please check to see if the assert/AV occurs while
compiling LazyRegister before entering a new bug for this failure.
===============


Вскрытие показало, что генерируется следующий код (рефлетро-C#):
    B b = new B(new A(0x7b));
    ref A prop = b.Prop;
    prop.X++;
    Console.WriteLine(b.Prop.X);

(рефлектор-IL):
.method public hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 3
    .locals init (
        [0] class B b,
        [1] valuetype A& aRef)
    L_0000: ldc.i4.s 0x7b
    L_0002: newobj instance void A::.ctor(int32)
    L_0007: newobj instance void B::.ctor(valuetype A)
    L_000c: stloc.0 
    L_000d: ldloc.0 
    L_000e: callvirt instance valuetype A B::get_Prop()
    L_0013: stloc.1 
    L_0014: ldloc.1 
    L_0015: ldloc.1 
    L_0016: ldfld int32 A::X
    L_001b: ldc.i4.1 
    L_001c: add.ovf 
    L_001d: stfld int32 A::X
    L_0022: ldloc.0 
    L_0023: callvirt instance valuetype A B::get_Prop()
    L_0028: ldfld int32 A::X
    L_002d: call void [mscorlib]System.Console::WriteLine(int32)
    L_0032: ret 
}


PeVerify под рукой нет. Но подозреваю, что IL не корректен.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.09.09 16:53
Оценка:
Здравствуйте, EvilChild, Вы писали:

VD>>Этот вопрос был поставлен уже давно. Только звучал он немного по другому — "Зачем нужны циклы если есть рекурсивные функции, функции высшего порядка и макросы?".


EC>А макросы сюда каким боком относятся? Первых 2х недостаточно?


А макры позволяют придать нужный синтаксис к имеющимся средствам.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Зачем нужны поля в .Net?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.09.09 19:57
Оценка: 2 (1) +2
Здравствуйте, VladD2, Вы писали:

VD>На мой взгляд было бы интересно обсудить какие просчеты были сделаны в виртуальных машинах и языках.


Ну вот из свеженького — в FW 4.0, в mscorlib добавлены интерфейсы IObservable/IObserver, что, на мой взгляд, является фактически признанием ошибочности внесения в CLR событий. Осталось слегка подрихтовать C#/VB, чтобы можно было использовать оператор += и синтаксис VB, и события станут полностью бесполезными . А там можно заодно и делегаты приговорить.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[8]: Зачем нужны поля в .Net?
От: Pavel Dvorkin Россия  
Дата: 24.09.09 04:47
Оценка:
Здравствуйте, MxKazan, Вы писали:

PD>>А когда вы его declare не так как в этом example, то вам придется это поле создать вручную и в свойстве set в него что-то занести.

MK>И тем не менее, я привел пример, когда поля в классе нет, если абстрагироваться от того, что генерит компилятор. Это поведение (генерацию поля) в теории можно легко изменить, если из языка устранить само понятие поля. Ну т.е. сделать что-то вроде свойств хранилищ (бывшие поля) и свойств с аксессорами

В принципе, конечно, ты прав, правда, это уже будет не .Net как она есть сейчас, а нечто иное. Можно и дальше пофантазировать — хранение всех этих свойств (бывших полей) в БД, полностью спроецированной в оперативную память.
With best regards
Pavel Dvorkin
Re[3]: Зачем нужны поля в .Net?
От: Pavel Dvorkin Россия  
Дата: 24.09.09 04:51
Оценка:
Здравствуйте, VladD2, Вы писали:

PD>>М-да... Судя по всему, следующий вопрос (через пару лет) будет — зачем нужны циклы, если есть LinQ


VD>Этот вопрос был поставлен уже давно. Только звучал он немного по другому — "Зачем нужны циклы если есть рекурсивные функции,


Реализация рекурсивной функции при нынешней архитектуре есть неявный цикл на стеке.
With best regards
Pavel Dvorkin
Re[2]: Зачем нужны поля в .Net?
От: Pavel Dvorkin Россия  
Дата: 24.09.09 05:02
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Я как-то уже думал на эту тему и пришел к выводу, что в языке можно было бы избавиться от лишней абстракции. Поля можно было бы переставлять как свойства с двумя публичными эксесорами. Это упростило бы язык и сделало бы более легким использование рефлексии (поля попросту можно было бы игнорировать во многих случаях).


Я бы проще это сформулировал. ИМХО реализация дефолтных свойств как она есть в C# сделана не с той стороны. Вместо того, чтобы делать свойства с теневым полем, надо было сделать поля с автоматическим созданием свойства. Есть, к примеру, поле string name — автоматом создается свойство string Name с простейшей реализацией. Не нравится — напиши его сам. Ну и для полносты картины атрибут [Nonpropertable] запрещающий это либо для всего класса, либо для конкретного поля.

VD>На мой взгляд было бы интересно обсудить какие просчеты были сделаны в виртуальных машинах и языках. И то как должны выглядеть более совершенные ВМ и ЯП.


Это не просчеты. Это просто развитие языка в конкретной исторической обстановке. Не могли быть классы в Фортране и раннем Бейсике, качественная рефлексия в С++ и идеи ФП — в C# 1.0. Всему свое время.
With best regards
Pavel Dvorkin
Re[3]: Зачем нужны поля в .Net?
От: anton_t Россия  
Дата: 24.09.09 05:23
Оценка: :))) :))) :))) :))
Здравствуйте, 9kpm66, Вы писали:

9>Здравствуйте, Lexxpin, Вы писали:


L>>А вы в курсе что такое свойство с точки зрения CLR?


9>А вы в курсе что такое CLR с точки зрения линуксоида?


А вы в курсе, что такое линуксоид с точки зрения свойства?
Re[3]: Зачем нужны поля в .Net?
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 24.09.09 07:25
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

VD>>На мой взгляд было бы интересно обсудить какие просчеты были сделаны в виртуальных машинах и языках. И то как должны выглядеть более совершенные ВМ и ЯП.


PD>Это не просчеты. Это просто развитие языка в конкретной исторической обстановке.


Павел, ну ты же сам не так давно рассуждал на тему о влиянии личностей на развитие индустрии. Есть мнение, что это развитие не столько языка, сколько людей, принимающих участие в его разработке. Если бы C# проектировался не командой Хейлсберга, а, скажем, Пейтоном-Джонсом и К, то сейчас бы речь шла о том, что не могло бы быть императивщины в первом шарпе

Я так понимаю, что проблема в необходимости, практически на каждом очередном витке этой "эволюции", поиска командой ответа на вопрос "а что делать с тем, что уже есть?" (т.е. обратной совместимости), а также о том, что шарп сильно завязан на среду выполнения (ну или наоборот несмотря на CLI, тут я хз, что первично), т.е. нужно принимать во внимание не только пожелания и планы архитекторов самого языка. И если бы упомянутые просчеты не были допущены изначально, то "развитие языка в конкретной исторической обстановке" протекало бы куда более динамично.

PD>Не могли быть классы в Фортране и раннем Бейсике,


Не потому ли, что идеи ООП если вообще и имели место в моменты рождения этих языков, то где-то ближе к зародышевому состоянию?

PD>качественная рефлексия в С++


А в С++ уже есть качественная рефлексия?

PD>и идеи ФП — в C# 1.0. Всему свое время.


А вот ФП как парадигма, в момент рождения шарпа, была уже более чем сформировавшейся (ибо она старше бейсика, AFAIK). Т.о. причины отсутствия ее поддержки в шарпе отличаются от причин отсутствия ООП в бейсике и фортране

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[3]: Зачем нужны поля в .Net?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.09.09 08:00
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Я бы проще это сформулировал. ИМХО реализация дефолтных свойств как она есть в C# сделана не с той стороны. Вместо того, чтобы делать свойства с теневым полем, надо было сделать поля с автоматическим созданием свойства. Есть, к примеру, поле string name — автоматом создается свойство string Name с простейшей реализацией. Не нравится — напиши его сам. Ну и для полносты картины атрибут [Nonpropertable] запрещающий это либо для всего класса, либо для конкретного поля.


Кошмар.

PD>Это не просчеты. Это просто развитие языка в конкретной исторической обстановке. Не могли быть классы в Фортране и раннем Бейсике, качественная рефлексия в С++ и идеи ФП — в C# 1.0. Всему свое время.


Идеи ФП в С# 1 может и не могли быть, но причины этого не технические.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[4]: Зачем нужны поля в .Net?
От: Pavel Dvorkin Россия  
Дата: 24.09.09 08:04
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Я бы проще это сформулировал. ИМХО реализация дефолтных свойств как она есть в C# сделана не с той стороны. Вместо того, чтобы делать свойства с теневым полем, надо было сделать поля с автоматическим созданием свойства. Есть, к примеру, поле string name — автоматом создается свойство string Name с простейшей реализацией. Не нравится — напиши его сам. Ну и для полносты картины атрибут [Nonpropertable] запрещающий это либо для всего класса, либо для конкретного поля.


AVK>Кошмар.


Убедительно!
With best regards
Pavel Dvorkin
Re[4]: Зачем нужны поля в .Net?
От: Pavel Dvorkin Россия  
Дата: 24.09.09 08:11
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Здравствуйте, Pavel Dvorkin, Вы писали:


VD>>>На мой взгляд было бы интересно обсудить какие просчеты были сделаны в виртуальных машинах и языках. И то как должны выглядеть более совершенные ВМ и ЯП.


PD>>Это не просчеты. Это просто развитие языка в конкретной исторической обстановке.


KV>Павел, ну ты же сам не так давно рассуждал на тему о влиянии личностей на развитие индустрии. Есть мнение, что это развитие не столько языка, сколько людей, принимающих участие в его разработке. Если бы C# проектировался не командой Хейлсберга, а, скажем, Пейтоном-Джонсом и К, то сейчас бы речь шла о том, что не могло бы быть императивщины в первом шарпе


KV>Я так понимаю, что проблема в необходимости, практически на каждом очередном витке этой "эволюции", поиска командой ответа на вопрос "а что делать с тем, что уже есть?" (т.е. обратной совместимости), а также о том, что шарп сильно завязан на среду выполнения (ну или наоборот несмотря на CLI, тут я хз, что первично), т.е. нужно принимать во внимание не только пожелания и планы архитекторов самого языка. И если бы упомянутые просчеты не были допущены изначально, то "развитие языка в конкретной исторической обстановке" протекало бы куда более динамично.


Вполне согласен. Но , сказав, "просто развитие языка в конкретной исторической обстановке", я вообще-то ничего плохого сказать не хотел.

PD>>Не могли быть классы в Фортране и раннем Бейсике,


KV>Не потому ли, что идеи ООП если вообще и имели место в моменты рождения этих языков, то где-то ближе к зародышевому состоянию?


May be. А may и not be. Я те времена хорошо помню. Не те проблемы нас занимали, и не те задачи мы решали. А задачи были более математические, вычислительные. Там алгоритмы первенствуют, а не организация. А ООП все же скорее организация, чем алгоритм. Во всяком случае, все, что можно сделать с ООП , можно сделать и без него (доказательство простое — можно написать на асме, а там нет ООП), а вот без алгоритма никакое ООП не поможет. Просто время не пришло.

PD>>качественная рефлексия в С++


KV>А в С++ уже есть качественная рефлексия?


Так я и говорю же — не могла.

PD>>и идеи ФП — в C# 1.0. Всему свое время.


KV>А вот ФП как парадигма, в момент рождения шарпа, была уже более чем сформировавшейся (ибо она старше бейсика, AFAIK). Т.о. причины отсутствия ее поддержки в шарпе отличаются от причин отсутствия ООП в бейсике и фортране


Почему отличаются ? Ты же сам говоришь — во времена царствия Фортрана ООП уже было. Но не было нужным. Так же как и ФП в C# 1.0.
With best regards
Pavel Dvorkin
Re[3]: Зачем нужны поля в .Net?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.09.09 15:05
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

VD>>Я как-то уже думал на эту тему и пришел к выводу, что в языке можно было бы избавиться от лишней абстракции. Поля можно было бы переставлять как свойства с двумя публичными эксесорами. Это упростило бы язык и сделало бы более легким использование рефлексии (поля попросту можно было бы игнорировать во многих случаях).


PD>Я бы проще это сформулировал. ИМХО реализация дефолтных свойств как она есть в C# сделана не с той стороны. Вместо того, чтобы делать свойства с теневым полем, надо было сделать поля с автоматическим созданием свойства. Есть, к примеру, поле string name — автоматом создается свойство string Name с простейшей реализацией. Не нравится — напиши его сам. Ну и для полносты картины атрибут [Nonpropertable] запрещающий это либо для всего класса, либо для конкретного поля.


http://nemerle.org/Accessor_macros
Вот только автосвойства по жизни удобнее.

VD>>На мой взгляд было бы интересно обсудить какие просчеты были сделаны в виртуальных машинах и языках. И то как должны выглядеть более совершенные ВМ и ЯП.


PD>Это не просчеты. Это просто развитие языка в конкретной исторической обстановке. Не могли быть классы в Фортране и раннем Бейсике, качественная рефлексия в С++ и идеи ФП — в C# 1.0. Всему свое время.


Есть и просчеты. АВК тут правильно заметил, что влеплять события и делегаты рантайм было не верно. Нужны были более базовые вещи — функциональные типы и набор стандартных интерфейсов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 26.09.09 18:48
Оценка: 90 (1) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Реализация рекурсивной функции при нынешней архитектуре есть неявный цикл на стеке.


А какая разница, как это реализуется, неужели от этого поменяется суть Впрочем, посмотрим, как...

Не знаю, что понимается под нынешней архитектурой... на примере x86

    mov eax, 5
@@: nop     ;
    dec eax ; тело цикла
    jnz @b  ;

В ассемблере нет функций или процедур, есть подпрограммы — участки кода, предназначенные для многократного вызова. В примере выше такой подпрограммой является команды обозначенные анонимной меткой @@. Вызывавется она (то есть, её адрес загружается в указатель инструкций IP) командой условного перехода jnz. Выход из подпрограммы осуществляется этой же командой, естественным инкрементом IP. Это возможно, поскольку подпрограмма вызывается только из одного места (поэтому же нет нужды использовать для вызова call, сохраняя в стеке адрес возврата).

Цикл — это просто короткое название вышеописанного рекурсивного вызова, один из частных случаев. Термин придумали, что бы проще понять рекурсию (т.к. для этого можно не понимать рекурсию).

Еще один частный случай (реализации) рекурсивного вызова:
    push continuation
    push @f
    push @f
    push @f
    push @f
@@: nop
    ret
continuation:

Можно придумать еще несколько, включая комбинации.



To zen it, следует забыть "ассемблер" Iczelion'а и Зубкова, с его С-шной идеологией и регламентированными конвенциями вызовов.

Параметры в подпрограмму могут передаваться например так:
call foo
dd 1
dd 2
call boo

Или так:
    mov ebp, @f
    jmp foo
    dd 1
    dd 2
@@:

В последнем случает стек и для сохранения адреса возврата не используется. Да и что такое стек, адресуемая регистром общего назначения esp память? А почему именно esp, только потому, что в CISC x86 есть удобные команды для этого? Вот в самом первом примере стек значений от 5 до 0 реализован всего на одном регистре eax без посторонней памяти.




.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Зачем нужны поля в .Net?
От: BulatZiganshin  
Дата: 27.09.09 09:46
Оценка: +1
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Павел, ну ты же сам не так давно рассуждал на тему о влиянии личностей на развитие индустрии. Есть мнение, что это развитие не столько языка, сколько людей, принимающих участие в его разработке. Если бы C# проектировался не командой Хейлсберга, а, скажем, Пейтоном-Джонсом и К, то сейчас бы речь шла о том, что не могло бы быть императивщины в первом шарпе


в Войне и мiре есть рассуждение о влиянии личности на историю. говоря кратко, значительно повлиять на историю может только человек, направление деятельности которого совпало с исторически обусловленным ходом развития. не мог spj оказаться во главе этого проекта — ибо MS интересовал коммерческий успех детища Х., а не теоретические изыски хаскеллеров. но если бы даже и оказался — созданный им продукт не пошёл бы у программистов, и ms проиграла бы в противостоянии сану, только и всего

в середине 90-х никто, включая наверно и самих spj и вадлера, не мог представить что через 10 лет процессоры таки станут многоядерными и это усилит интерес к фп так что оно станет естественной заменой ооп. а представь себе что этого бы не произошло и вместо фп стало популярно лп и ты точно так же сидел бы здесь переживвал что ms не догадалось поставить во главе своего проекта ковалевского
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 28.09.09 05:07
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Реализация рекурсивной функции при нынешней архитектуре есть неявный цикл на стеке.


GN>А какая разница, как это реализуется, неужели от этого поменяется суть Впрочем, посмотрим, как...


GN>Не знаю, что понимается под нынешней архитектурой... на примере x86


GN>
GN>    mov eax, 5
GN>@@: nop     ;
GN>    dec eax ; тело цикла
GN>    jnz @b  ;
GN>

GN>В ассемблере нет функций или процедур, есть подпрограммы — участки кода, предназначенные для многократного вызова. В примере выше такой подпрограммой является команды обозначенные анонимной меткой @@. Вызывавется она (то есть, её адрес загружается в указатель инструкций IP) командой условного перехода jnz. Выход из подпрограммы осуществляется этой же командой, естественным инкрементом IP. Это возможно, поскольку подпрограмма вызывается только из одного места (поэтому же нет нужды использовать для вызова call, сохраняя в стеке адрес возврата).

Я бы все-таки предпочел не играть с терминологией. Для асма x86 подпрограмма — это все же то, что заканчивается командой ret (или iret — для подпрограммы обработки прерывания). То, что ты написал, можно , конечно, при желании назвать подпрограммой... В философском плане оно верно, а в руководстве по асму будет не кошерно.

GN>Цикл — это просто короткое название вышеописанного рекурсивного вызова, один из частных случаев. Термин придумали, что бы проще понять рекурсию (т.к. для этого можно не понимать рекурсию).


Формально с этим аргументом можно согласиться. Я бы так сказал — в теории цикл сводится к рекурсии. Но это формально, а в реальности... команду LOOP придумали тоже, чтобы лучше понять рекурсию ?

GN>Параметры в подпрограмму могут передаваться например так:

<skipped>

На ассемблере делать можно как угодно и что угодно. Можно, например, вызвать подпрограмму с помощью команды ret , надеюсь, тебе этот способ известен. Можно выйти из нее без ret. Можно параметры передать твоим способом или вообще как-то еще. Но все это не более чем упражнения, может, и любопытные в плане обучения хакерству, но не имеющие отношения к реальному программированию, где параметры надо передавать в соответствии с calling convention, иначе получите все, что вам причитается


GN>В последнем случает стек и для сохранения адреса возврата не используется. Да и что такое стек, адресуемая регистром общего назначения esp память? А почему именно esp, только потому, что в CISC x86 есть удобные команды для этого?


Именно. Потому что команды push и pop работают с esp, а с другими регистрами не работают.

>Вот в самом первом примере стек значений от 5 до 0 реализован всего на одном регистре eax без посторонней памяти.


Твои примеры любопытны, но , мягко выражаясь, надуманны, и к реальному коду имеют весьма косвенное отношение. Даже если этот код не сгенерирован компилятором, а написан вручную на асме.
With best regards
Pavel Dvorkin
Re[2]: А он уже должен быть "встроен" в свойства
От: ylem  
Дата: 28.09.09 06:30
Оценка: -1
А он уже должен быть "встроен" в свойства
Re[6]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 28.09.09 07:52
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Я бы все-таки предпочел не играть с терминологией. Для асма x86 подпрограмма — это все же то, что заканчивается командой ret (или iret — для подпрограммы обработки прерывания).


Осторожнее. Если двигаться в этом направлении, то можно показать, что inline фнукции в С вовсе не функции

В принципе, при чём здесь x86? Я выбрал его, т.к. это наиболее известный из ассемблеров, соответсвенно большее количество людей смогут понять код. В других архитектурах команды ret может не быть вовсе. Не вижу причин обобщать этот частный случай.

PD> То, что ты написал, можно , конечно, при желании назвать подпрограммой... В философском плане оно верно, а в руководстве по асму будет не кошерно.


Я бы сказал, что такое кошерное руководство будет учить не асму, а С с нетрадиционным синтаксисом.

PD>Формально с этим аргументом можно согласиться. Я бы так сказал — в теории цикл сводится к рекурсии. Но это формально, а в реальности... команду LOOP придумали тоже, чтобы лучше понять рекурсию ?


LOOPcc придумана с единственной целью: получить более компактный бинарный код. Подобно ret, call и т.п. CISC командам.

PD>На ассемблере делать можно как угодно и что угодно. Можно, например, вызвать подпрограмму с помощью команды ret , надеюсь, тебе этот способ известен. Можно выйти из нее без ret. Можно параметры передать твоим способом или вообще как-то еще. Но все это не более чем упражнения, может, и любопытные в плане обучения хакерству, но не имеющие отношения к реальному программированию, где параметры надо передавать в соответствии с calling convention, иначе получите все, что вам причитается


Если бы я начинал с x86, вероятно, думал бы так же. Однако я видел приличное количество "коробочного" софта изнутри, где использовались именно такие "экзотические" способы передачи данных. Тяжело на том же Z80 передавать параметры через стек, а регистров мало.

PD>Потому что команды push и pop работают с esp, а с другими регистрами не работают.


Иными словами, ничего не мешает использовать другие регистры, если отказаться от call\ret. Разве что, получим больший по объёму машкод, приблизившись к RISC.

PD>Твои примеры любопытны, но , мягко выражаясь, надуманны, и к реальному коду имеют весьма косвенное отношение. Даже если этот код не сгенерирован компилятором, а написан вручную на асме.


Похожий код может произвести, например, транслятор forth. Примеры приводились с единственной целью — показать, что в ассеблере нет каких-то определённых рамок, кроме тех, что мы сами себе навязываем (определение цикла, в данном случае).
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[7]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 28.09.09 12:50
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


GN>Осторожнее. Если двигаться в этом направлении, то можно показать, что inline фнукции в С вовсе не функции


Совершенно верно. Они являются функциями языка С/C++, но не подпрограммами в машинном коде.

GN>В принципе, при чём здесь x86? Я выбрал его, т.к. это наиболее известный из ассемблеров, соответсвенно большее количество людей смогут понять код. В других архитектурах команды ret может не быть вовсе. Не вижу причин обобщать этот частный случай.


Ну так мы далеко уйдем. Если нет ret, то, наверное, нет и call, так ? Или они есть, но иначе. Если уж на то пошло, то в архитектуре IBM-360/370 не было аппаратного стека, и мое утверждение насчет рекурсии как цикла на стеке там явно неприменимо. В общем, обсуждать все платоформы на свете я не буду. А ret все же существует. Как и call . Пусть только на x86/x64

PD>> То, что ты написал, можно , конечно, при желании назвать подпрограммой... В философском плане оно верно, а в руководстве по асму будет не кошерно.


GN>Я бы сказал, что такое кошерное руководство будет учить не асму, а С с нетрадиционным синтаксисом.


Руководство, которое можно бы написать по твоим советам насчет асма, будет не руководством по асму, а руководством по трюкам на асме. Не обижайся.


PD>>Формально с этим аргументом можно согласиться. Я бы так сказал — в теории цикл сводится к рекурсии. Но это формально, а в реальности... команду LOOP придумали тоже, чтобы лучше понять рекурсию ?


GN>LOOPcc придумана с единственной целью: получить более компактный бинарный код.


По сравнению с чем ? jne и т.п ? Да. Но дело-то не в этом, а в том, что машинные команды включают в себя специальную команду цикла. Как понятие он есть. И не абстрактный цикл, а именно цикл с инкрементом или декрементом. В конце концов я вполне могу обойтись без цикла и в С++ с презренным goto, но есть же в языке цикл!

>Подобно ret, call и т.п. CISC командам.


ret и call вообще из иной оперы, не смешивай. И уж loop делалась отнюдь не из философский идей насчет CISC и RISC. Не забывай — этой команде и этой архитектуре скоро 30 лет будет

GN>Если бы я начинал с x86, вероятно, думал бы так же. Однако я видел приличное количество "коробочного" софта изнутри, где использовались именно такие "экзотические" способы передачи данных. Тяжело на том же Z80 передавать параметры через стек, а регистров мало.


Помню эту прелесть, как же. Ну могу сказать. что я и на x86 использовал нестандартные способы передачи параметров, и очень даже нестандартные. Например, доводилось такое писать

mov, eax,0

Если думаешь, что здесь 0 засылается — глубоко неправ. Перед вызовом этой функции будет найден адрес этого нуля, и вместо него прямо в код записан параметр. Причина та же — регистров мало

Но это все трюки. Хорошие или нет — можно обсуждать. А традиционное программирование все же к трюкам относится не очень хорошо.

PD>>Потому что команды push и pop работают с esp, а с другими регистрами не работают.


GN>Иными словами, ничего не мешает использовать другие регистры, если отказаться от call\ret. Разве что, получим больший по объёму машкод, приблизившись к RISC.


Может, и да, правда, приблизившись на 1 мм, не более . Отказаться от call/ret можно, можно отказаться от многих команд, например, от всего, что появилось в 386 и позже , например, сканирование битов и т.д. — писали же такое раньше без этих команд! Можно в С++ отказаться от цикла for, неужели while на мне хватит ? Можно переделать архитектуру, обеспечив полную ортогональность регистров. Можно просто на Итаниум перейти. Но пока мы в рамках x86/64, давай будем исходить из того, что там есть.

PD>>Твои примеры любопытны, но , мягко выражаясь, надуманны, и к реальному коду имеют весьма косвенное отношение. Даже если этот код не сгенерирован компилятором, а написан вручную на асме.


GN>Похожий код может произвести, например, транслятор forth. Примеры приводились с единственной целью — показать, что в ассеблере нет каких-то определённых рамок, кроме тех, что мы сами себе навязываем (определение цикла, в данном случае).


Вполне согласен. Я же и писал — на нем можно все. Но при одном условии — проект и будет целиком на асме. Как только здесь примет участие C++ или Delphi — извольте соблюдать calling convention. Если с Фортом будешь сопрягать — извольте его правила соблюдать, я их не знаю, но они обязательно есть.
With best regards
Pavel Dvorkin
Re[3]: Зачем нужны поля в .Net?
От: _FRED_ Черногория
Дата: 28.09.09 15:36
Оценка:
Здравствуйте, AndrewVK, Вы писали:

VD>>На мой взгляд было бы интересно обсудить какие просчеты были сделаны в виртуальных машинах и языках.


AVK>Ну вот из свеженького — в FW 4.0, в mscorlib добавлены интерфейсы IObservable/IObserver,


А можешь показать, когда и конкретно куда добавлены Я как-то ни рефлектором в сборке mscorlib (от десятки, 10.0.20506.1 Beta1) найти не могу, ни в МСДН.

AVK>что, на мой взгляд, является фактически признанием ошибочности внесения в CLR событий. Осталось слегка подрихтовать C#/VB, чтобы можно было использовать оператор += и синтаксис VB, и события станут полностью бесполезными . А там можно заодно и делегаты приговорить.


+1
Help will always be given at Hogwarts to those who ask for it.
Re[8]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 28.09.09 15:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ну так мы далеко уйдем. Если нет ret, то, наверное, нет и call, так ? Или они есть, но иначе. Если уж на то пошло, то в архитектуре IBM-360/370 не было аппаратного стека, и мое утверждение насчет рекурсии как цикла на стеке там явно неприменимо.


Интересно получается — в одном случае утверждение верно, в другом нет. В то же время, моя интерпретация подходит во всех случаях

PD>Руководство, которое можно бы написать по твоим советам насчет асма, будет не руководством по асму, а руководством по трюкам на асме. Не обижайся.


Не дождётесь И вот почему смешно: в ассемблере континуации — "трюк", а в других языках — "мегафича".

Кстати, вот такой пример на тему циклов (я употребляю это слово, т.к. оно короче, но подразумеваю описанное ранее)

Есть 32 бита в регистре (не конь в вуккуме, а, например, маска пикселей) нужно их как-то обработать по-одному. Как будет решаться задача императивно, циклом? В лоб:
    mov eax, [pixels]  
    mov ecx, 32  
@@: shr eax, 1  ; копируем очередной бит в Carry Flag
    ;
    ; тут что-то делаем с битом
    ;
    dec ecx  ; итерируем цикл
    jnz @b

Если немного подумать, то на ассемблере это делается так:
    mov eax, [pixels]
    stc    ; используем Carry Flag как "маркер" конца битовой последовательности.
@@: rcr eax, 1 ; копируем очередной бит в Carry Flag. за счёт цикличности сдвига, меркер перейдёт в младший бит на первом проходе.
    ;
    ; тут что-то делаем с битом
    ;
    or  eax, eax  ; проверяем, остался ли бит маркера.
    jnz @b
Счётчик цикла убран за не надобностью тратить лишний регистр. Как бы так "императивно" объяснить вышепроисходящее, без упоминаний о битах? С другой стороны, можно сказать что здесь рекурсивный вызов, где параметром передаётся "остаток" последовательности.

GN>>LOOPcc придумана с единственной целью: получить более компактный бинарный код.


PD>По сравнению с чем ? jne и т.п ? Да. Но дело-то не в этом, а в том, что машинные команды включают в себя специальную команду цикла.


В этом именно и дело. Отдельный опкод — для экономии памяти. Отдельное определение для частного случая рекурсии — для кратости изложения.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Зачем нужны поля в .Net?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.09.09 17:53
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А можешь показать, когда


Нет

_FR> и конкретно куда


mscorlib, System namespace

_FR> добавлены Я как-то ни рефлектором в сборке mscorlib (от десятки, 10.0.20506.1 Beta1) найти не могу, ни в МСДН.


Скоро будет beta 2.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[9]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 29.09.09 05:31
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Ну так мы далеко уйдем. Если нет ret, то, наверное, нет и call, так ? Или они есть, но иначе. Если уж на то пошло, то в архитектуре IBM-360/370 не было аппаратного стека, и мое утверждение насчет рекурсии как цикла на стеке там явно неприменимо.


GN>Интересно получается — в одном случае утверждение верно, в другом нет. В то же время, моя интерпретация подходит во всех случаях


Подумал еще раз.

Вообще-то, коль скоро речь идет о дефинициях, то их можно создавать как кому угодно. Ты — свои, я свои. Так что если хочешь определять подпрограмму как некий произвольный код, я тебе в этом воспрепятствовать не могу . Что же касается меня, то я считаю, что подпрограмма тем и отличается от всякого другого кода, что a)может быть вызвана из нескольких мест (и вообще говоря, любых мест) и b) как следствие из этого, не хранит в себе явно адрес возврата в вызывающий код. Этот адрес передается ей каким-то иным способом, вследствие чего он может быть различным. Не обязательно через стек, может, через регистры (с сохранением их для рекурсии) или еще как-то. Но тот факт, что ее можно вызвать не из одного места и что она сама не знает адреса возврата — ИМХО обязателен. Еще раз — все это игры в дефиниции, так что ты впроаве завести понятие подпрограммы, не удовлетоворяющее этим правилам. Если ты это сделаешь — мы будем иметь 2 вида подпрограмм

PD>>Руководство, которое можно бы написать по твоим советам насчет асма, будет не руководством по асму, а руководством по трюкам на асме. Не обижайся.


GN>Не дождётесь И вот почему смешно: в ассемблере континуации — "трюк", а в других языках — "мегафича".


Не понял. Можно пример ?

GN>Кстати, вот такой пример на тему циклов (я употребляю это слово, т.к. оно короче, но подразумеваю описанное ранее)


GN>Есть 32 бита в регистре (не конь в вуккуме, а, например, маска пикселей) нужно их как-то обработать по-одному. Как будет решаться задача императивно, циклом? В лоб:

GN>
GN>    mov eax, [pixels]  
GN>    mov ecx, 32  
GN>@@: shr eax, 1  ; копируем очередной бит в Carry Flag
GN>    ;
GN>    ; тут что-то делаем с битом
GN>    ;
GN>    dec ecx  ; итерируем цикл
GN>    jnz @b
GN>

GN>Если немного подумать, то на ассемблере это делается так:
GN>
GN>    mov eax, [pixels]
GN>    stc    ; используем Carry Flag как "маркер" конца битовой последовательности.
GN>@@: rcr eax, 1 ; копируем очередной бит в Carry Flag. за счёт цикличности сдвига, меркер перейдёт в младший бит на первом проходе.
GN>    ;
GN>    ; тут что-то делаем с битом
GN>    ;
GN>    or  eax, eax  ; проверяем, остался ли бит маркера.
GN>    jnz @b
GN>
Счётчик цикла убран за не надобностью тратить лишний регистр.


М-да. Как-то мне казалось, что идея обработки до завершающего элемента без явного счетчика цикла не является особенно новой. И без всякого ассемблера она уже сто лет используется, например, в ASCIIZ строках, где завершающий ноль играет примерно ту же роль, что и флаг С в твоем примере. Так что извини, но я не понял, к чему все это.

>Как бы так "императивно" объяснить вышепроисходящее, без упоминаний о битах? С другой стороны, можно сказать что здесь рекурсивный вызов, где параметром передаётся "остаток" последовательности.


Да, конечно, при желании можно все свести или псевдосвести к рекурсии. Например, длину ASCIIZ строки можно вычислить рекурсивно. Примерно так

int len(char*p)
{
if(!*p)
return 0;
else return len(p+1) + 1;
}

Но я все же ни писать такое, ни учить студентов писать такое не буду, а если они такое напишут — устрою им выволочку. Ибо нечего ерундой заниматься.
With best regards
Pavel Dvorkin
Re[10]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.09.09 05:51
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Да, конечно, при желании можно все свести или псевдосвести к рекурсии. Например, длину ASCIIZ строки можно вычислить рекурсивно. Примерно так


PD>int len(char*p)

PD>{
PD>if(!*p)
PD> return 0;
PD>else return len(p+1) + 1;
PD>}

PD>Но я все же ни писать такое, ни учить студентов писать такое не буду, а если они такое напишут — устрою им выволочку. Ибо нечего ерундой заниматься.

Конечно, такая рекурсия не является хвостовой и может вызвать переполнение стека даже там где есть оптимизация хвостовой рекурсии.
Re[11]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 29.09.09 08:33
Оценка:
Здравствуйте, gandjustas, Вы писали:


PD>>Да, конечно, при желании можно все свести или псевдосвести к рекурсии. Например, длину ASCIIZ строки можно вычислить рекурсивно. Примерно так


PD>>int len(char*p)

PD>>{
PD>>if(!*p)
PD>> return 0;
PD>>else return len(p+1) + 1;
PD>>}

PD>>Но я все же ни писать такое, ни учить студентов писать такое не буду, а если они такое напишут — устрою им выволочку. Ибо нечего ерундой заниматься.

G>Конечно, такая рекурсия не является хвостовой и может вызвать переполнение стека даже там где есть оптимизация хвостовой рекурсии.

Это-то как раз меня не столь уж и волнует. Переполнение стека в С++ устроить очень несложно, но с этим как-нибудь справимся. Дело не в этом, а в том, что рекурсивное решение здесь просто ни к чему. Оно здесь за уши притянуто.
With best regards
Pavel Dvorkin
Re[12]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.09.09 08:47
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, gandjustas, Вы писали:



PD>>>Да, конечно, при желании можно все свести или псевдосвести к рекурсии. Например, длину ASCIIZ строки можно вычислить рекурсивно. Примерно так


PD>>>int len(char*p)

PD>>>{
PD>>>if(!*p)
PD>>> return 0;
PD>>>else return len(p+1) + 1;
PD>>>}

PD>>>Но я все же ни писать такое, ни учить студентов писать такое не буду, а если они такое напишут — устрою им выволочку. Ибо нечего ерундой заниматься.

G>>Конечно, такая рекурсия не является хвостовой и может вызвать переполнение стека даже там где есть оптимизация хвостовой рекурсии.

PD>Это-то как раз меня не столь уж и волнует. Переполнение стека в С++ устроить очень несложно, но с этим как-нибудь справимся. Дело не в этом, а в том, что рекурсивное решение здесь просто ни к чему. Оно здесь за уши притянуто.


Ничего не притянуто. Рекурсивное решение требует меньше знания языка, чем решение с циклом, кроме того обладает семантикой выражения, что лучше понимается математиками. И самое главное не содержит изменяемых значений, поэтому очень сложно написать неправльно в таком виде.

Вот как-то так
int len(char *p)
{
  return *p?(len(p+1) + 1):0;
}
Re[13]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 29.09.09 09:56
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Ничего не притянуто. Рекурсивное решение требует меньше знания языка, чем решение с циклом


Это не аргумент.


>кроме того обладает семантикой выражения, что лучше понимается математиками



Это тоже. Какое мне дело, как они понимают, лучше или хуже.

> И самое главное не содержит изменяемых значений, поэтому очень сложно написать неправльно в таком виде.


И этот аргумент сомнителен.

А вот эффективность его ниже, потому что если цикл может быть реализован по регистру, рекурсия (если ее реализовать как положено) — это работа со стеком, то есть с памятью.
With best regards
Pavel Dvorkin
Re[14]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.09.09 10:11
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, gandjustas, Вы писали:


G>>Ничего не притянуто. Рекурсивное решение требует меньше знания языка, чем решение с циклом

PD>Это не аргумент.
Если вопрос касается обучения, то очень даже аргумент. В том же SICP в одном семестре умещается полезных знаний програмимрования гораздо больше, чем в среднестатистическом курсе на с\паскаль.


>>кроме того обладает семантикой выражения, что лучше понимается математиками

PD>Это тоже. Какое мне дело, как они понимают, лучше или хуже.
Ну да, читаемость программ — совершенно неважное свойство.

>> И самое главное не содержит изменяемых значений, поэтому очень сложно написать неправльно в таком виде.

PD>И этот аргумент сомнителен.
Да ты че? Корректные программы писать уже не надо?

PD>А вот эффективность его ниже

А вот это действительно сомнительный агрумент, так как очевидно пример с таким вычислением длины строки к реально жизни отношения не имеет. Во многих случаях длина строки хранится вместе со строкой и её не надо считать таким ублюдочным способом, и только тяжелое наследие С не позволяет повсеместно применять такой подход.

PD>...потому что если цикл может быть реализован по регистру, рекурсия (если ее реализовать как положено) — это работа со стеком, то есть с памятью.

Если рекурсию реализовать как положено, то она тоже прекратится в цикл в машинных кодах. Только не все компиляторы так умеют.
Re[14]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 29.09.09 11:11
Оценка: 3 (2)
Здравствуйте, Pavel Dvorkin, Вы писали:


PD>А вот эффективность его ниже, потому что если цикл может быть реализован по регистру, рекурсия (если ее реализовать как положено) — это работа со стеком, то есть с памятью.


Правильная хвостовая рекурсия современными C++ компиляторами компилируется не менее эффективно чем цикл:

int len(char *p, size_t l = 0)
{
if(!*p)
    return l;
    
return len(p + 1, l + 1);
}



?len@@YAHPADI@Z PROC                    ; len
; _p$ = ecx
; _l$ = eax

; 5    : if(!*p)

    cmp    BYTE PTR [ecx], 0
    je    SHORT $LN7@len
$LL4@len:

; 6    :     return l;
; 7    :     
; 8    : return len(p + 1, l + 1);

    inc    ecx
    inc    eax
    cmp    BYTE PTR [ecx], 0
    jne    SHORT $LL4@len
$LN7@len:

; 9    : }

    ret    0
?len@@YAHPADI@Z ENDP                    ; len
Re[15]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 29.09.09 12:30
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Здравствуйте, gandjustas, Вы писали:


G>>>Ничего не притянуто. Рекурсивное решение требует меньше знания языка, чем решение с циклом

PD>>Это не аргумент.
G>Если вопрос касается обучения, то очень даже аргумент. В том же SICP в одном семестре умещается полезных знаний програмимрования гораздо больше, чем в среднестатистическом курсе на с\паскаль.

До сих пор никаких проблем с обучением не было. Рекурсия была, роль ее подчиненная. Не надо на ровном месте проблемы создавать.


>>>кроме того обладает семантикой выражения, что лучше понимается математиками

PD>>Это тоже. Какое мне дело, как они понимают, лучше или хуже.
G>Ну да, читаемость программ — совершенно неважное свойство.

Опять не надо так. Во-первых, эффективность важнее, по крайней мере для меня. Во-вторых, что такого нечитаемого и непонятного в обычном цикле ты нашел. Если он не понятен — тому, кто его читает надо профессию сменить, потому что он должен быть понятен после 2 месяцев обучения. Раз и навсегда.

>>> И самое главное не содержит изменяемых значений, поэтому очень сложно написать неправльно в таком виде.

PD>>И этот аргумент сомнителен.
G>Да ты че? Корректные программы писать уже не надо?

А с циклом писать корректные программы так таки совсем уж невозможно ? Писали, пишем и будем писать.

PD>>А вот эффективность его ниже

G>А вот это действительно сомнительный агрумент, так как очевидно пример с таким вычислением длины строки к реально жизни отношения не имеет.

Безусловно. Я его и привел как пример искусственный.

>Во многих случаях длина строки хранится вместе со строкой


Только при этом ее посчитали. Впрочем, мне дискуссии на эту тему уже очень надоели.



PD>>...потому что если цикл может быть реализован по регистру, рекурсия (если ее реализовать как положено) — это работа со стеком, то есть с памятью.

G>Если рекурсию реализовать как положено, то она тоже прекратится в цикл в машинных кодах. Только не все компиляторы так умеют.

Точнее сказать, никто не умеет. Потому что по calling convention, которые надо соблюдать, можно, конечно, аргументы передавать и через регистры, если их хватит, а вот адрес возврата всегда заносится в стек. По крайней мере в x86.
With best regards
Pavel Dvorkin
Re[15]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 29.09.09 12:42
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:



PD>>А вот эффективность его ниже, потому что если цикл может быть реализован по регистру, рекурсия (если ее реализовать как положено) — это работа со стеком, то есть с памятью.


FR>Правильная хвостовая рекурсия современными C++ компиляторами компилируется не менее эффективно чем цикл:


Да, впечатляет. Но ты пошел на искусственный прием — добавил новый аргумент к функции, которой он совсем не нужен. И не надо ссылаться на то, что у него есть дефолтное значение — это функция языка С вообще-то, а не С++. Все равно игра не стоит свеч. И во имя рекурсии портить сигнатуры функций я не готов.
With best regards
Pavel Dvorkin
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 29.09.09 12:51
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Да, впечатляет. Но ты пошел на искусственный прием — добавил новый аргумент к функции, которой он совсем не нужен. И не надо ссылаться на то, что у него есть дефолтное значение — это функция языка С вообще-то, а не С++. Все равно игра не стоит свеч. И во имя рекурсии портить сигнатуры функций я не готов.


Не порти, для этого есть и перегрузка (для C++) и просто вспомогательная функция с другим названием (для си).
Да я и не призываю тебя писать в этом стиле просто показываю что эффективность уже не проблема.
Re[17]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 29.09.09 13:09
Оценка:
Здравствуйте, FR, Вы писали:

FR>Не порти, для этого есть и перегрузка (для C++) и просто вспомогательная функция с другим названием (для си).


То есть на С придется еще одну функцию завести ? А из программы какую вызывать — рекурсивную или вспомогательную ? Вспомогательная ведь нерекурсивная.

FR>Да я и не призываю тебя писать в этом стиле просто показываю что эффективность уже не проблема.


Я согласен с тем, что ты показал возможность реализации рекурсии без стека. Если быть точнее, то компилятор реализовал рекурсивную функцию С++ без рекурсивной подпрограммы в машинных кодах. Но заплатил ты за это ИМХО слишком дорого. А в реальной ситуации мне либо придется портить таким образом сигнатуры и тем самым вносить массу непонятности в код (исходники мало кто смотрит, а внешний интерфейс должен быть ясен и логичен), либо оставить сигнатуры как есть, но тогда компилятор реализует рекурсивный вызов в кодах. И то и другое вряд ли хорошо. Игра не стои свеч.
With best regards
Pavel Dvorkin
Re[18]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 29.09.09 13:34
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>То есть на С придется еще одну функцию завести ? А из программы какую вызывать — рекурсивную или вспомогательную ? Вспомогательная ведь нерекурсивная.


Вызывать основную, она не будет рекурсивной и будет доступна публично, вспомогательная рекурсивная и выполняет всю работу:

static int len_r(char *p, size_t l)
{
if(!*p)
    return l;
    
return len_r(p + 1, l + 1);
}

int len(char *p)
{
return len_r(p, 0);
}


Это практический типичный паттерн в функциональных языках, правда обычно вспомогательная рекурсивная функция делается не отдельной а вложенной.

FR>>Да я и не призываю тебя писать в этом стиле просто показываю что эффективность уже не проблема.


PD>Я согласен с тем, что ты показал возможность реализации рекурсии без стека. Если быть точнее, то компилятор реализовал рекурсивную функцию С++ без рекурсивной подпрограммы в машинных кодах.


Для функциональных языков развертка хвостовой рекурсии норма.

PD>Но заплатил ты за это ИМХО слишком дорого.


По моему практически бесплатно.

PD>А в реальной ситуации мне либо придется портить таким образом сигнатуры и тем самым вносить массу непонятности в код (исходники мало кто смотрит, а внешний интерфейс должен быть ясен и логичен), либо оставить сигнатуры как есть, но тогда компилятор реализует рекурсивный вызов в кодах. И то и другое вряд ли хорошо. Игра не стои свеч.


Нет все разрешимо, смотри выше.
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.09.09 17:47
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>>Здравствуйте, gandjustas, Вы писали:


G>>>>Ничего не притянуто. Рекурсивное решение требует меньше знания языка, чем решение с циклом

PD>>>Это не аргумент.
G>>Если вопрос касается обучения, то очень даже аргумент. В том же SICP в одном семестре умещается полезных знаний програмимрования гораздо больше, чем в среднестатистическом курсе на с\паскаль.
PD>До сих пор никаких проблем с обучением не было. Рекурсия была, роль ее подчиненная. Не надо на ровном месте проблемы создавать.
Аргумент в духе "мы всегда так делаем"?

>>>>кроме того обладает семантикой выражения, что лучше понимается математиками

PD>>>Это тоже. Какое мне дело, как они понимают, лучше или хуже.
G>>Ну да, читаемость программ — совершенно неважное свойство.

PD>Опять не надо так. Во-первых, эффективность важнее, по крайней мере для меня. Во-вторых, что такого нечитаемого и непонятного в обычном цикле ты нашел. Если он не понятен — тому, кто его читает надо профессию сменить, потому что он должен быть понятен после 2 месяцев обучения. Раз и навсегда.

Вопрос не в конкретном цикле, а в общем подходе.
Важно ведь не написать конкретное вычисление длины строки в цикле, а понять общение подходы к обработке последовательностей.

>>>> И самое главное не содержит изменяемых значений, поэтому очень сложно написать неправльно в таком виде.

PD>>>И этот аргумент сомнителен.
G>>Да ты че? Корректные программы писать уже не надо?
PD>А с циклом писать корректные программы так таки совсем уж невозможно ? Писали, пишем и будем писать.
Снова вопрос не в конкретном цикле, а в общем подходе.


PD>>>А вот эффективность его ниже

G>>А вот это действительно сомнительный агрумент, так как очевидно пример с таким вычислением длины строки к реально жизни отношения не имеет.
PD>Безусловно. Я его и привел как пример искусственный.

>>Во многих случаях длина строки хранится вместе со строкой

PD>Только при этом ее посчитали. Впрочем, мне дискуссии на эту тему уже очень надоели.
Да ну? Строковые литералы в программе уже компилируются вместе с длиной, все функции, которые читают строки из вне уже знают её длину на момент возврата управления программе. Любюые операции со строками оперируют уже известной длиной.


PD>>>...потому что если цикл может быть реализован по регистру, рекурсия (если ее реализовать как положено) — это работа со стеком, то есть с памятью.

G>>Если рекурсию реализовать как положено, то она тоже прекратится в цикл в машинных кодах. Только не все компиляторы так умеют.

PD>Точнее сказать, никто не умеет. Потому что по calling convention, которые надо соблюдать, можно, конечно, аргументы передавать и через регистры, если их хватит, а вот адрес возврата всегда заносится в стек. По крайней мере в x86.

Много кто умеет оптимизировать хвостовую рекурсию.
Re[4]: Зачем нужны поля в .Net?
От: EvilChild Ниоткуда  
Дата: 29.09.09 17:59
Оценка: 22 (1)
Здравствуйте, _FRED_, Вы писали:

_FR>А можешь показать, когда и конкретно куда добавлены Я как-то ни рефлектором в сборке mscorlib (от десятки, 10.0.20506.1 Beta1) найти не могу, ни в МСДН.

Отсюда качаем исходники Silverlight Toolkit и ищем среди них сборку System.Reactive.dll.
now playing: Gui Boratto — I Feel Love
Re[19]: Зачем нужны циклы если есть рекурсивные функции
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 29.09.09 18:03
Оценка:
Здравствуйте, FR, Вы писали:

FR>Это практический типичный паттерн в функциональных языках


Не только в функциональных.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[10]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 29.09.09 21:03
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Вообще-то, коль скоро речь идет о дефинициях, то их можно создавать как кому угодно. Ты — свои, я свои. Так что если хочешь определять подпрограмму как некий произвольный код, я тебе в этом воспрепятствовать не могу .


Хоть выше я и писал, что подпрограмма — это код, для меня любая программа на ассемблере представляет прежде всего данные. Потому что я вижу опкод (или мнемонику) и смотрю в документации (или памяти) что оно делает. Таким же образом работает процессор (я так понимаю его работу) — читает из памяти байты и интерпретирует их. Такой подход позволяет с лёгкостью определить, например, что mov eax, 0 изменяет 2 (общедоступных) регистра (ради эксперимента — попробуй устроить опрос у студентов — если хоть один назовёт цифру больше 1, соглашусь, что другой подход тоже верен ).

PD> Что же касается меня, то я считаю, что подпрограмма тем и отличается от всякого другого кода, что a)может быть вызвана из нескольких мест (и вообще говоря, любых мест)


"Моя" подпрограмма отвечает этом условию, будучи оформленной в виде макроса

PD> и b) как следствие из этого, не хранит в себе явно адрес возврата в вызывающий код.


"Явно" в данном случае субъективное понятие. Любая расположенная в памяти команда "хранит" свой адрес и адрес последующей за ней команды. А пока мы смотрим на исходный текст на ассемблере — явно там этих адресов нигде нет.

PD>Еще раз — все это игры в дефиниции, так что ты впроаве завести понятие подпрограммы, не удовлетоворяющее этим правилам. Если ты это сделаешь — мы будем иметь 2 вида подпрограмм


Отлично, значит буду продолжать использовать своё, как более обобщённое — на мой взгляд, оно лучше отражает возможность выполнения рекурсивных функций на Машине Тьюринга

PD>>>Руководство, которое можно бы написать по твоим советам насчет асма, будет не руководством по асму, а руководством по трюкам на асме. Не обижайся.


GN>>Не дождётесь И вот почему смешно: в ассемблере континуации — "трюк", а в других языках — "мегафича".


PD>Не понял. Можно пример ?


Континуаций? Были ж раньше, и названы трюками.
    push f2
    call f1
    ...
f1: ret
f2: ret


PD>М-да. Как-то мне казалось, что идея обработки до завершающего элемента без явного счетчика цикла не является особенно новой. И без всякого ассемблера она уже сто лет используется, например, в ASCIIZ строках, где завершающий ноль играет примерно ту же роль, что и флаг С в твоем примере.


Да, новой не является. Пример с ASCIIZ — широко известный из учебников частный случай. И, что странно — зная про ASCIIZ, люди продолжают писать первый вариант цикла обработки битов. Попробу найти хоть одного человека, кто напишет 2й (можно изменить условия задачи, что бы было решабельно на ЯВУ).

PD> Так что извини, но я не понял, к чему все это.

Как бы так "императивно" объяснить вышепроисходящее, без упоминаний о битах?

.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 29.09.09 21:15
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Но ты пошел на искусственный прием — добавил новый аргумент к функции, которой он совсем не нужен.


Подобный приём применён в моём примере
Автор: gear nuke
Дата: 28.09.09
с 32 битами, помимо битов-данных добавлен аргумент "конец последовательности". Если же его убрать, получится оверхед
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[19]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 05:49
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>То есть на С придется еще одну функцию завести ? А из программы какую вызывать — рекурсивную или вспомогательную ? Вспомогательная ведь нерекурсивная.


FR>Вызывать основную, она не будет рекурсивной и будет доступна публично, вспомогательная рекурсивная и выполняет всю работу:


Ну да, классика, именно так обычно и делают. Но ИМХО игра стоит свеч, если рекурсия действительно что-то дает.


FR>>>Да я и не призываю тебя писать в этом стиле просто показываю что эффективность уже не проблема.


PD>>Я согласен с тем, что ты показал возможность реализации рекурсии без стека. Если быть точнее, то компилятор реализовал рекурсивную функцию С++ без рекурсивной подпрограммы в машинных кодах.


FR>Для функциональных языков развертка хвостовой рекурсии норма.


Ну и бог с ними, меня они мало интересуют

FR>Нет все разрешимо, смотри выше.


Я не спорю, разрешимо, но во имя чего ? Чего ты тут в этой len добился ? Не говоря уж о том, что strlen сделана совсем иначе. Привожу кусочек


main_loop:
        mov     eax,dword ptr [ecx]     ; read 4 bytes
        mov     edx,7efefeffh
        add     edx,eax
        xor     eax,-1
        xor     eax,edx
        add     ecx,4
        test    eax,81010100h
        je      short main_loop
        ; found zero byte in the loop


Здесь вообще не побайтно, как видишь, работают. И не из высоких теоретических соображений, а для скорости. А руководствуясь этими соображениями, можно сделать код красивым, только работать он будет гораздо медленнее.
With best regards
Pavel Dvorkin
Re[11]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 06:06
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Вообще-то, коль скоро речь идет о дефинициях, то их можно создавать как кому угодно. Ты — свои, я свои. Так что если хочешь определять подпрограмму как некий произвольный код, я тебе в этом воспрепятствовать не могу .


GN>Хоть выше я и писал, что подпрограмма — это код, для меня любая программа на ассемблере представляет прежде всего данные.


Что-то совсем какая-то схоластика началась. Или ты мне принцип фон-Неймана (хранимой программы) решил объяснить ? Если да, то спасибо, я его знаю. Если нет — к чему все это ?

>Потому что я вижу опкод (или мнемонику) и смотрю в документации (или памяти) что оно делает. Таким же образом работает процессор (я так понимаю его работу) — читает из памяти байты и интерпретирует их. Такой подход позволяет с лёгкостью определить, например, что mov eax, 0 изменяет 2 (общедоступных) регистра


Как говорил Остап Бендер, конгениально. Спасибо, обрадовал.

>(ради эксперимента — попробуй устроить опрос у студентов — если хоть один назовёт цифру больше 1, соглашусь, что другой подход тоже верен ).


Лично мой ответ — один. Потому что это по существу. Второй тоже меняется, верно, но только для этой команды мне до этого изменения в общем, и дела нет.

PD>> Что же касается меня, то я считаю, что подпрограмма тем и отличается от всякого другого кода, что a)может быть вызвана из нескольких мест (и вообще говоря, любых мест)


GN>"Моя" подпрограмма отвечает этом условию, будучи оформленной в виде макроса


Ты уже пытался меня поймать на inline функциях на С. Теперь хочешь на асме ? Макрос — не элемент машинных команд, нет в машинном коде никаких макросов. Макрос — элемент языка ассемблер. Если тебе угодно считать, что на ассемблере у тебя есть макрос-подпрограмма, считай на здоровье, но в машинных кодах никаких подпрограмм нет — не хватает только подпрограмм , тело которых присутствует в коде десяток раз

PD>> и b) как следствие из этого, не хранит в себе явно адрес возврата в вызывающий код.


GN>"Явно" в данном случае субъективное понятие. Любая расположенная в памяти команда "хранит" свой адрес и адрес последующей за ней команды. А пока мы смотрим на исходный текст на ассемблере — явно там этих адресов нигде нет.


Казуистикой заниматься изволишь. Можно подумать, что ты не поянл о чем речь идет.

PD>>Еще раз — все это игры в дефиниции, так что ты впроаве завести понятие подпрограммы, не удовлетоворяющее этим правилам. Если ты это сделаешь — мы будем иметь 2 вида подпрограмм


GN>Отлично, значит буду продолжать использовать своё, как более обобщённое — на мой взгляд, оно лучше отражает возможность выполнения рекурсивных функций на Машине Тьюринга


Да бога ради. Пойди в магазин, купи себе машину Тьюринга, поставь ее на стол и программируй для нее

PD>>>>Руководство, которое можно бы написать по твоим советам насчет асма, будет не руководством по асму, а руководством по трюкам на асме. Не обижайся.


GN>>>Не дождётесь И вот почему смешно: в ассемблере континуации — "трюк", а в других языках — "мегафича".


PD>>Не понял. Можно пример ?


GN>Континуаций? Были ж раньше, и названы трюками.

GN>
GN>    push f2
GN>    call f1
GN>    ...
GN>f1: ret
GN>f2: ret
GN>


Не континуаций (aka трюки), а в каких других языках такие трюки есть мегафича.


PD>>М-да. Как-то мне казалось, что идея обработки до завершающего элемента без явного счетчика цикла не является особенно новой. И без всякого ассемблера она уже сто лет используется, например, в ASCIIZ строках, где завершающий ноль играет примерно ту же роль, что и флаг С в твоем примере.


GN>Да, новой не является. Пример с ASCIIZ — широко известный из учебников частный случай. И, что странно — зная про ASCIIZ, люди продолжают писать первый вариант цикла обработки битов. Попробу найти хоть одного человека, кто напишет 2й (можно изменить условия задачи, что бы было решабельно на ЯВУ).


Ну посмотри, например, ассемблерный код strlen. Зная про ASCIIZ, люди из MS тем не менее не стали реализовать тупой проход (зато простой и понятный! ах как хорошо понятный , а устроили работу с DWORDами, далеко не столь ясную, да еще и на ассемблере. Из чего следует, что не все так просто, как тебе кажется. Как минимум — надо померить и тот,и другой алгоритмы по скорости.
With best regards
Pavel Dvorkin
Re[20]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 30.09.09 06:10
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ну да, классика, именно так обычно и делают. Но ИМХО игра стоит свеч, если рекурсия действительно что-то дает.


Угу, плюс позволяет писать в функциональном стиле, используя где возможно только чистые функции, что повышает надежность кода.


FR>>Нет все разрешимо, смотри выше.


PD>Я не спорю, разрешимо, но во имя чего ? Чего ты тут в этой len добился ? Не говоря уж о том, что strlen сделана совсем иначе. Привожу кусочек


Тут ты передергиваешь, это уже совсем другой алгоритм, ничто ни мешает его же реализовать также на си рекурсивно.

............

PD>Здесь вообще не побайтно, как видишь, работают. И не из высоких теоретических соображений, а для скорости. А руководствуясь этими соображениями, можно сделать код красивым, только работать он будет гораздо медленнее.


Не будет медленнее если алгоритмы совпадают.
Re[17]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 06:17
Оценка:
Здравствуйте, gandjustas, Вы писали:

PD>>До сих пор никаких проблем с обучением не было. Рекурсия была, роль ее подчиненная. Не надо на ровном месте проблемы создавать.

G>Аргумент в духе "мы всегда так делаем"?

Нет, все гораздо серьезнее. Программиста, который не умеет использовать рекурсию, но знает все остальное, вполне можно принять на работу. В конце концов я первые 5 лет своей карьеры знал о ней только теоретически — на Фортране официально рекурсии нет (некоторые компиляторы позволяют). Объяснить ему рекурсию — дело максимум на час, научиться ему самому ее использовать — ну пусть еще неделя. И все.
А человека, не умеющего писать циклы, как программиста рассматривать вообще нельзя. В школу!

>>>>>кроме того обладает семантикой выражения, что лучше понимается математиками

PD>>>>Это тоже. Какое мне дело, как они понимают, лучше или хуже.
G>>>Ну да, читаемость программ — совершенно неважное свойство.

G>Вопрос не в конкретном цикле, а в общем подходе.

G>Важно ведь не написать конкретное вычисление длины строки в цикле, а понять общение подходы к обработке последовательностей.

Извини за грубость, но в гробу видел я эти общие подходы!!! Понять — дело замечательное, только, пожалуйста, после того, как понял, оставь это понимание для общего развития, а при реальной работе исходи не из общих подходов, а из реальной задачи, при программировании которой. может быть, лучше сделать вопреки всем общим подходам и самым безупречным теоретическим соображениям.

Вот тебе простой пример — та же strlen. Общие подходы, то ли цикл по байтам до нуля, то ли рекурсия, то ли хвостовая, то ли бесхвостая . А теперь смотрим текст strlen. Вот кусочек


main_loop:
        mov     eax,dword ptr [ecx]     ; read 4 bytes
        mov     edx,7efefeffh
        add     edx,eax
        xor     eax,-1
        xor     eax,edx
        add     ecx,4
        test    eax,81010100h
        je      short main_loop
        ; found zero byte in the loop


Ну и как с общим подходом ? С высоким идейными соображениями как ? Из какого общего подхода следует, что в этой задаче есть какая-то работа с 4-х байтниками и xor ? Вот то-то и оно!



PD>>А с циклом писать корректные программы так таки совсем уж невозможно ? Писали, пишем и будем писать.

G>Снова вопрос не в конкретном цикле, а в общем подходе.

См. выше.



>>>Во многих случаях длина строки хранится вместе со строкой

PD>>Только при этом ее посчитали. Впрочем, мне дискуссии на эту тему уже очень надоели.
G>Да ну? Строковые литералы в программе уже компилируются вместе с длиной

На С ?
With best regards
Pavel Dvorkin
Re[21]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 06:24
Оценка:
Здравствуйте, FR, Вы писали:

FR>Угу, плюс позволяет писать в функциональном стиле, используя где возможно только чистые функции, что повышает надежность кода.


Пишите, на здоровье.

PD>>Я не спорю, разрешимо, но во имя чего ? Чего ты тут в этой len добился ? Не говоря уж о том, что strlen сделана совсем иначе. Привожу кусочек


FR>Тут ты передергиваешь, это уже совсем другой алгоритм, ничто ни мешает его же реализовать также на си рекурсивно.


Упаси боже! Ты хочешь быстродействие компьютеров раза в 1.5 уменьшить ?

FR>............


PD>>Здесь вообще не побайтно, как видишь, работают. И не из высоких теоретических соображений, а для скорости. А руководствуясь этими соображениями, можно сделать код красивым, только работать он будет гораздо медленнее.


FR>Не будет медленнее если алгоритмы совпадают.


То есть ты утверждаешь, что компилятор делает столь же эффективный код, что и оптимальный код на асме ? Вроде все же не так. Да и зачем тогда его ребята из MS на асме написали ? Да не его только, а весь набор из string.h. Поищи в форуме по C++, там вопрос о быстродействии strcpy вроде не раз обсуждался.
With best regards
Pavel Dvorkin
Re[18]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 30.09.09 06:27
Оценка: 1 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Нет, все гораздо серьезнее. Программиста, который не умеет использовать рекурсию, но знает все остальное, вполне можно принять на работу. В конце концов я первые 5 лет своей карьеры знал о ней только теоретически — на Фортране официально рекурсии нет (некоторые компиляторы позволяют). Объяснить ему рекурсию — дело максимум на час, научиться ему самому ее использовать — ну пусть еще неделя. И все.


Проблема в том что чтобы понять рекурсию нужен "скачек понимания", поэтому да некоторым людям можно это объяснить за пять минут, но некоторые вообще не могут понять.

PD>А человека, не умеющего писать циклы, как программиста рассматривать вообще нельзя. В школу!


По моим наблюдениям люди не понимающие рекурсию также не понимают и указатели и вообще любые не самые тривиальные понятия в программировании. Поэтому человека не понимающего рекурсию по моему тоже как программиста рассматривать нельзя.
Re[18]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 30.09.09 06:30
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, gandjustas, Вы писали:


PD>>>До сих пор никаких проблем с обучением не было. Рекурсия была, роль ее подчиненная. Не надо на ровном месте проблемы создавать.

G>>Аргумент в духе "мы всегда так делаем"?

PD>Нет, все гораздо серьезнее. Программиста, который не умеет использовать рекурсию, но знает все остальное, вполне можно принять на работу.

Программиста, который умеет использовать рекурсию, но не знает все остальное, тоже вполне можно принять на работу.
Вообще на работу можно принять кого угодно.

>>>>>>кроме того обладает семантикой выражения, что лучше понимается математиками

PD>>>>>Это тоже. Какое мне дело, как они понимают, лучше или хуже.
G>>>>Ну да, читаемость программ — совершенно неважное свойство.

G>>Вопрос не в конкретном цикле, а в общем подходе.

G>>Важно ведь не написать конкретное вычисление длины строки в цикле, а понять общение подходы к обработке последовательностей.

PD>Извини за грубость, но в гробу видел я эти общие подходы!!! Понять — дело замечательное, только, пожалуйста, после того, как понял, оставь это понимание для общего развития, а при реальной работе исходи не из общих подходов, а из реальной задачи, при программировании которой. может быть, лучше сделать вопреки всем общим подходам и самым безупречным теоретическим соображениям.

Пустая болтовня.


PD>Вот тебе простой пример — та же strlen. Общие подходы, то ли цикл по байтам до нуля, то ли рекурсия, то ли хвостовая, то ли бесхвостая . А теперь смотрим текст strlen. Вот кусочек



PD>
PD>main_loop:
PD>        mov     eax,dword ptr [ecx]     ; read 4 bytes
PD>        mov     edx,7efefeffh
PD>        add     edx,eax
PD>        xor     eax,-1
PD>        xor     eax,edx
PD>        add     ecx,4
PD>        test    eax,81010100h
PD>        je      short main_loop
PD>        ; found zero byte in the loop

PD>


PD>Ну и как с общим подходом ? С высоким идейными соображениями как ? Из какого общего подхода следует, что в этой задаче есть какая-то работа с 4-х байтниками и xor ? Вот то-то и оно!

Тебе еще раз повторить про ущербность самого наличия функции strlen, которая проистекает от ущербности наследния C?



>>>>Во многих случаях длина строки хранится вместе со строкой

PD>>>Только при этом ее посчитали. Впрочем, мне дискуссии на эту тему уже очень надоели.
G>>Да ну? Строковые литералы в программе уже компилируются вместе с длиной

PD>На С ?

На C вообще все плохо.
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 30.09.09 06:33
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

FR>>Тут ты передергиваешь, это уже совсем другой алгоритм, ничто ни мешает его же реализовать также на си рекурсивно.


PD>Упаси боже! Ты хочешь быстродействие компьютеров раза в 1.5 уменьшить ?


Конечно ровно в 1.512345678777 раза

FR>>Не будет медленнее если алгоритмы совпадают.


PD>То есть ты утверждаешь, что компилятор делает столь же эффективный код, что и оптимальный код на асме ? Вроде все же не так. Да и зачем тогда его ребята из MS на асме написали ? Да не его только, а весь набор из string.h. Поищи в форуме по C++, там вопрос о быстродействии strcpy вроде не раз обсуждался.


Нет это ты куда в сторону от обсуждения уходишь.
Алгоритм другой, так как чтение идет кусками в 4 байта, сделать это на си также можно и будет скорее всего быстрее, чем при чтении побайтно, при этом и рекурсивная и не рекурсивная программы будут работать одинаково быстро.
Re[12]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 30.09.09 08:12
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Если нет — к чему все это ?


К "если хочешь определять подпрограмму как некий произвольный код"

PD>Лично мой ответ — один. Потому что это по существу. Второй тоже меняется, верно, но только для этой команды мне до этого изменения в общем, и дела нет.


Напрасно. Я неоднократно сталкивался с ошибками из-за такого упрощенного взгляда на вещи.

Из известных примеров — Windows при обработке 2х байтного int 3.

PD>Ты уже пытался меня поймать на inline функциях на С. Теперь хочешь на асме ?


Я лишь пытаюсь показать вред искуственно вводимых ограничений.

PD> Макрос — не элемент машинных команд, нет в машинном коде никаких макросов. Макрос — элемент языка ассемблер.


Если заниматься буквоедством, то b в ассемблере макросов нет. Они есть в макроассемблерах и выше.

Макроассемблеры позволяют делать так:
proc my_subroutine
;....
endproc

;...

mov edi, my_subroutine(0, ecx)

При этом, в зависимости от размера my_subroutine, может быть сделан "автоматический" выбор — инлайн, или call.

Либо есть второй вариант — загнать себя в рамки без макросов и писать всё как настоящий джедай руками. Я даже знаю один такой успешный проект — flat assembler

PD> Если тебе угодно считать, что на ассемблере у тебя есть макрос-подпрограмма, считай на здоровье, но в машинных кодах никаких подпрограмм нет —


В машкодах нет, но на этом уровне абстракции никто и не работает.

PD>не хватает только подпрограмм , тело которых присутствует в коде десяток раз


Вызов подпрограммы может быть больше её самой по размеру

PD>Не континуаций (aka трюки), а в каких других языках такие трюки есть мегафича.


Scheme например. Я к тому, что использование их может быть вполне нормальной практикой, зачем называть это рюками

PD>Ну посмотри, например, ассемблерный код strlen. Зная про ASCIIZ, люди из MS тем не менее не стали реализовать тупой проход (зато простой и понятный! ах как хорошо понятный , а устроили работу с DWORDами, далеко не столь ясную, да еще и на ассемблере. Из чего следует, что не все так просто, как тебе кажется. Как минимум — надо померить и тот,и другой алгоритмы по скорости.


Ну что ж, я увижу там сравнение по 4 байта за раз, и всё тот же рекурсивный вызов анонимной подпрограммы.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[23]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 08:59
Оценка:
Здравствуйте, FR, Вы писали:

PD>>Упаси боже! Ты хочешь быстродействие компьютеров раза в 1.5 уменьшить ?


FR>Конечно ровно в 1.512345678777 раза


Именно. Причем я эту величину берусь предсказать даже без профайлера

FR>>>Не будет медленнее если алгоритмы совпадают.


PD>>То есть ты утверждаешь, что компилятор делает столь же эффективный код, что и оптимальный код на асме ? Вроде все же не так. Да и зачем тогда его ребята из MS на асме написали ? Да не его только, а весь набор из string.h. Поищи в форуме по C++, там вопрос о быстродействии strcpy вроде не раз обсуждался.


FR>Нет это ты куда в сторону от обсуждения уходишь.

FR>Алгоритм другой, так как чтение идет кусками в 4 байта

Да.

>сделать это на си также можно


Да.

>и будет скорее всего быстрее, чем при чтении побайтно, при этом и рекурсивная и не рекурсивная программы будут работать одинаково быстро.


Такие вещи надо доказывать. Напиши, померим. И в любом случае — должно быть не хуже, чем существующая ассемблерная версия, иначе в топку оба С варианта. Чтобы не было медленнее в 1.512345678777 раза

Кстати, в той же RTL есть C вариант strlen


size_t __cdecl strlen (
        const char * str
        )
{
        const char *eos = str;

        while( *eos++ ) ;

        return( eos - str - 1 );
}

Зачем он там — не понимаю.
With best regards
Pavel Dvorkin
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 30.09.09 08:59
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А с циклом писать корректные программы так таки совсем уж невозможно ? Писали, пишем и будем писать.


Мощное заявление. Которое неплохо бы подтвержить примером программ (написанной, находящейся в процессе написания, и, самое сложное, программы, которая еще не написана, но безусловно будет написана) с циклами и, желательно, > 10 KLOC каждая. Разумеется, с доказательством корректности для всех трех случаев.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[24]: уточнение
От: Pavel Dvorkin Россия  
Дата: 30.09.09 09:00
Оценка:
PD>Кстати, в той же RTL есть C вариант strlen


Не в RTL, конечно, а в исходниках, прилагаемых к VS
With best regards
Pavel Dvorkin
Re[24]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 30.09.09 09:14
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

FR>>Конечно ровно в 1.512345678777 раза


PD>Именно. Причем я эту величину берусь предсказать даже без профайлера


зря

>>и будет скорее всего быстрее, чем при чтении побайтно, при этом и рекурсивная и не рекурсивная программы будут работать одинаково быстро.


PD>Такие вещи надо доказывать. Напиши, померим. И в любом случае — должно быть не хуже, чем существующая ассемблерная версия, иначе в топку оба С варианта. Чтобы не было медленнее в 1.512345678777 раза


Доказывать что сишная четырехбайтная будет быстрее чем сишная однобайтная, не вижу смысла.
Ассемблер не всегда пременим, и ты его сюда притащил просто что увести разговор.

Ассемблерная кстати довольно тупая, при большом желании, которого у меня нет, вполне можно сишную более быструю написать чем эта конкретная ассемблерная.

PD>Кстати, в той же RTL есть C вариант strlen


....

PD>Зачем он там — не понимаю.


intel itanium
Re[13]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 09:16
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Если нет — к чему все это ?


GN>К "если хочешь определять подпрограмму как некий произвольный код"


Так я же не возражаю. Если хочешь — определяй. Пусть будут подпрограммы_gear_nuke и подпрограммы_Pavel_Dvorkin

PD>>Лично мой ответ — один. Потому что это по существу. Второй тоже меняется, верно, но только для этой команды мне до этого изменения в общем, и дела нет.


GN>Напрасно. Я неоднократно сталкивался с ошибками из-за такого упрощенного взгляда на вещи.


Сколько раз писал mov eax, 0 — ошибок, связанных с тем, что при этом меняется EIP — не было. Другие были

GN>Из известных примеров — Windows при обработке 2х байтного int 3.


М.б. Я честно сказать, не в курсе — вроде он был однобайтный. Мне такое самому писать не доводилось.

PD>>Ты уже пытался меня поймать на inline функциях на С. Теперь хочешь на асме ?


GN>Я лишь пытаюсь показать вред искуственно вводимых ограничений.


За нашу и вашу свободу!

PD>> Макрос — не элемент машинных команд, нет в машинном коде никаких макросов. Макрос — элемент языка ассемблер.


GN>Если заниматься буквоедством, то b в ассемблере макросов нет. Они есть в макроассемблерах и выше.


Верно. Принимаю. Во встроенном в C++ ассемблере макросов нет. Но ты же хотел макросы . Пусть в макроассемблере.

GN>Макроассемблеры позволяют делать так:

GN>
GN>proc my_subroutine
GN>;....
GN>endproc

GN>;...

GN>mov edi, my_subroutine(0, ecx)
GN>

GN>При этом, в зависимости от размера my_subroutine, может быть сделан "автоматический" выбор — инлайн, или call.

Ну и прекрасно. То же, что и с inline в С — то ли будет, то ли нет, в зависимости от опций и настроения компилятора и фазы Луны. Еще есть __forceinline

GN>Либо есть второй вариант — загнать себя в рамки без макросов



Зачем ?

>и писать всё как настоящий джедай руками


В кодах ?


PD>> Если тебе угодно считать, что на ассемблере у тебя есть макрос-подпрограмма, считай на здоровье, но в машинных кодах никаких подпрограмм нет —


GN>В машкодах нет, но на этом уровне абстракции никто и не работает.


Как это никто не работает ? Люди — да. А процессор так вроде именно на этом уровне и работает. А выясняли мы вроде вопрос о подпрограммах именно в машинном коде. С командой ret , точнее, с командой из таких-то байтов (под рукой их нет)

PD>>не хватает только подпрограмм , тело которых присутствует в коде десяток раз


GN>Вызов подпрограммы может быть больше её самой по размеру


Не увиливай. Я ничего не говорил о вызове и размере. Может, конечно. Только вот если код встраивается вместо вызова — это просто встраивание кода, а не вызов.

PD>>Не континуаций (aka трюки), а в каких других языках такие трюки есть мегафича.


GN>Scheme например.

Scheme я не знаю и маргинальными языками не интересуюсь. Можно пример из какого-нибудь известного большинству языка? Pascal, C, C++, Java, C#, Basic, Fortran ...

>Я к тому, что использование их может быть вполне нормальной практикой, зачем называть это рюками


Может. При условии, что в том языке/системе это принято. В свое время (Win16) была calling conention Pascal (слева направо, стек очищает вызываемая). Если кто-то сейчас решится ее использовать -это будет ничем не оправданный трюк.


PD>>Ну посмотри, например, ассемблерный код strlen. Зная про ASCIIZ, люди из MS тем не менее не стали реализовать тупой проход (зато простой и понятный! ах как хорошо понятный , а устроили работу с DWORDами, далеко не столь ясную, да еще и на ассемблере. Из чего следует, что не все так просто, как тебе кажется. Как минимум — надо померить и тот,и другой алгоритмы по скорости.


GN>Ну что ж, я увижу там сравнение по 4 байта за раз, и всё тот же рекурсивный вызов анонимной подпрограммы.


Я так подозреваю, что Hello, World в твоем определении тоже рекурсивна
With best regards
Pavel Dvorkin
Re[5]: Зачем нужны поля в .Net?
От: _FRED_ Черногория
Дата: 30.09.09 09:50
Оценка:
Здравствуйте, EvilChild, Вы писали:

_FR>>А можешь показать, когда и конкретно куда добавлены Я как-то ни рефлектором в сборке mscorlib (от десятки, 10.0.20506.1 Beta1) найти не могу, ни в МСДН.

EC>Отсюда качаем исходники Silverlight Toolkit и ищем среди них сборку System.Reactive.dll.

Мда уж. Это действительно то, что будет во второй бете? А почему в System.Collections.Generic
Help will always be given at Hogwarts to those who ask for it.
Re[25]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 10:17
Оценка:
Здравствуйте, FR, Вы писали:

PD>>Такие вещи надо доказывать. Напиши, померим. И в любом случае — должно быть не хуже, чем существующая ассемблерная версия, иначе в топку оба С варианта. Чтобы не было медленнее в 1.512345678777 раза


FR>Доказывать что сишная четырехбайтная будет быстрее чем сишная однобайтная, не вижу смысла.


Естественно. Ты докажи, что рекурсивная С-шная 4 — байтовая будет не медленее чем нерекурсивная С-шная 4-байтная, а они обе — чем ассемблерная 4-бафтовая, которой все мы пользуемся.

FR>Ассемблер не всегда пременим, и ты его сюда притащил просто что увести разговор.


Всегда применим, по крайней мере, пока речь идет о неуправляемом коде.

FR>Ассемблерная кстати довольно тупая, при большом желании, которого у меня нет, вполне можно сишную более быструю написать чем эта конкретная ассемблерная.


Если ты это сделаешь, благодарное человечество будет тебя помнить! . Но увы, у тебя нет желания заслужить его благодарность

PD>>Кстати, в той же RTL есть C вариант strlen


FR>....


PD>>Зачем он там — не понимаю.


FR>intel itanium


Не уверен. Там, кстати нет и x64 ассемблерной версии strlen. А дизассемблер показывает вот такое

000000014000101A mov rdi,qword ptr [rdx]
000000014000101D or rcx,0FFFFFFFFFFFFFFFFh
0000000140001021 xor eax,eax
0000000140001023 repne scas byte ptr [rdi]
0000000140001025 not rcx
0000000140001028 sub rcx,1
000000014000102C mov dword ptr [n (1400035E4h)],ecx



Как насчет рекурсивности команды repne scas ?
With best regards
Pavel Dvorkin
Re[19]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 10:20
Оценка:
Здравствуйте, FR, Вы писали:

PD>>А человека, не умеющего писать циклы, как программиста рассматривать вообще нельзя. В школу!


FR>По моим наблюдениям люди не понимающие рекурсию


Не понимающие или не использующие? Если он ее понять не может — да, гнать. Но не использовать вполне может. Я о ней знал с самого начала карьеры, а использовал считанное число раз. Сколько я циклов написал за свою карьеру -учету не поддается.
With best regards
Pavel Dvorkin
Re[17]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 10:27
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А с циклом писать корректные программы так таки совсем уж невозможно ? Писали, пишем и будем писать.


K>Мощное заявление. Которое неплохо бы подтвержить примером программ (написанной, находящейся в процессе написания, и, самое сложное, программы, которая еще не написана, но безусловно будет написана


Я как-то с трудом понимаю, как это можно привести пример программы, которая еще не написана, но безусловно будет написана . Независимо от того, какими средствами она будет написана.


>) с циклами и, желательно, > 10 KLOC каждая. Разумеется, с доказательством корректности для всех трех случаев.


То есть ты хочешь. чтобы для еще не написанной программы я привел доказательства ее корректности ? Индульгенции только римский папа выдавал, да и то давно уже не выдает.

А если серьезнее, то... Корректность программы отнюдь не значит, что я готов утверждать, что в ней нет ошибок вообще. А к доказательствам корректности я вообще отношусь с иронией. Я просто имел в виду, что уже 50 с лишним лет люди пишут программы, в них используют циклы, и , в общем, это все более или менее корректно работает , и никакой необходимости что-то тут менять я не вижу. Да никто и не будет.
With best regards
Pavel Dvorkin
Re[19]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 10:35
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Программиста, который умеет использовать рекурсию, но не знает все остальное, тоже вполне можно принять на работу.


Бери. Я его не возьму. Я его выгоню, если мне такорй студент попадется. Впрочем, не попадется — до 3 курса такие не доживают.

G>Вообще на работу можно принять кого угодно.


Можно. Секретаршей, машинисткой, менеджером, уборщицей, курьером.

PD>>Извини за грубость, но в гробу видел я эти общие подходы!!! Понять — дело замечательное, только, пожалуйста, после того, как понял, оставь это понимание для общего развития, а при реальной работе исходи не из общих подходов, а из реальной задачи, при программировании которой. может быть, лучше сделать вопреки всем общим подходам и самым безупречным теоретическим соображениям.

G>Пустая болтовня.

Замечательный аргумент. Главное — убедительно


G>Тебе еще раз повторить про ущербность самого наличия функции strlen, которая проистекает от ущербности наследния C?


Кто мне тут про общие принципы говорил ? Забудь про С и строки , и оставайся просто при общих принципах. Есть набор байтов, заканчивающийся нулем, найти сколько там байтов до нуля. Абстрактно, никакие не строки. Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>На C вообще все плохо.




Вот якут Колодезников за отгон чужого оленя в тайгу получил в 1932 году
три года и, по правилам глубокомысленных перемещений, с родной Колымы был
послан отбывать под Ленинград. Отбыл, и в самом Ленинграде был, и привез
семье ярких тканей, и все ж много лет потом жаловался землякам и зэкам,
присланным из Ленинграда:
-- Ох, скучно там у вас! Ох, плохо!..

(C) А. Солженицын, Архипелаг Гулаг
With best regards
Pavel Dvorkin
Re[18]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 30.09.09 11:12
Оценка: +1 -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Я как-то с трудом понимаю, как это можно привести пример программы, которая еще не написана, но безусловно будет написана

PD>То есть ты хочешь. чтобы для еще не написанной программы я привел доказательства ее корректности ?

Вы верно ухватили суть. Доказать это невозможно. Поэтому слова "Писали, пишем и будем писать" в данном случае даже более пусты, чем межзвездное пространство.

PD>Корректность программы отнюдь не значит, что я готов утверждать, что в ней нет ошибок вообще.


Анекдот.

PD>Я просто имел в виду, что уже 50 с лишним лет люди пишут программы, в них используют циклы, и , в общем, это все более или менее корректно работает , и никакой необходимости что-то тут менять я не вижу. Да никто и не будет.


Да 50 лет это же все равно, что один миг. Та же олдовайская технология, например, использовалась почти два миллиона лет. Казалось бы, зачем что-то менять? Но, тем не менее, находятся безответственные товарищи, которые не ценят стабильность, не понимают, что технологии, они как вино — с каждым годом без изменений только лучше и лучше.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[26]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 30.09.09 11:16
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Естественно. Ты докажи, что рекурсивная С-шная 4 — байтовая будет не медленее чем нерекурсивная С-шная 4-байтная, а они обе — чем ассемблерная 4-бафтовая, которой все мы пользуемся.


Я уже показал что разницы между рекурсивной и не рекурсивной нет. А ассемблерной мы все не пользуемся в gcc например ее нет.

PD>Всегда применим, по крайней мере, пока речь идет о неуправляемом коде.


Угу язык си придумали именно поэтому.

FR>>Ассемблерная кстати довольно тупая, при большом желании, которого у меня нет, вполне можно сишную более быструю написать чем эта конкретная ассемблерная.


PD>Если ты это сделаешь, благодарное человечество будет тебя помнить! . Но увы, у тебя нет желания заслужить его благодарность


Не будет, даже не заметит. Так как в реальных программах даже если ускорить strlen в десять раз никакого ускорения вообще не будет.

PD>Как насчет рекурсивности команды repne scas ?


с этим к gear nuke
Re[20]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 30.09.09 11:21
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Не понимающие или не использующие? Если он ее понять не может — да, гнать. Но не использовать вполне может. Я о ней знал с самого начала карьеры, а использовал считанное число раз. Сколько я циклов написал за свою карьеру -учету не поддается.


Конечно не понимающие.
Но неиспользование по моему не повод для гордости
Re[21]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 11:33
Оценка:
Здравствуйте, FR, Вы писали:

FR>Конечно не понимающие.

FR>Но неиспользование по моему не повод для гордости

Да какая там гордость. Не требовалось просто, вот и все. Впрочем, несколько раз все же написал. Обход дерева и т.п.
With best regards
Pavel Dvorkin
Re[27]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 30.09.09 11:40
Оценка:
Здравствуйте, FR, Вы писали:


FR>Я уже показал что разницы между рекурсивной и не рекурсивной нет. А ассемблерной мы все не пользуемся в gcc например ее нет.


Уверен ? Приведи кусок кода из дизассемблера/отладчика

PD>>Всегда применим, по крайней мере, пока речь идет о неуправляемом коде.


FR>Угу язык си придумали именно поэтому.


При чем тут C ? Асм-вставки есть, например, и на Delphi, я уж не говорю о подключении extern функций из DLL, написанных на асме — это практически в любом языке можно.

FR>Не будет, даже не заметит. Так как в реальных программах даже если ускорить strlen в десять раз никакого ускорения вообще не будет.


Ох, не уверен. Ведь не одну strlen придется переписать, а весь string.h, если уж реализовать твою идею всерьез. А это обработка всех строк в С-коде, а это немалая часть этого кода, а этого кода тоже немало

PD>>Как насчет рекурсивности команды repne scas ?


FR>с этим к gear nuke


With best regards
Pavel Dvorkin
Re[28]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 30.09.09 12:00
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Уверен ? Приведи кусок кода из дизассемблера/отладчика


Нету под рукой исходников, но простая логика подсказывает что при поддержке такого количества платформ ассемблер отдыхает.

PD>>>Всегда применим, по крайней мере, пока речь идет о неуправляемом коде.


FR>>Угу язык си придумали именно поэтому.


PD>При чем тут C ? Асм-вставки есть, например, и на Delphi, я уж не говорю о подключении extern функций из DLL, написанных на асме — это практически в любом языке можно.


При том что появление языка си как раз и затолкало ассемблер в ту очень узкую нишу в которой он сейчас находится.
Про дельфи не надо, я уже потрохов VCL накушался, там ассемблер по бедности, не смогли борландовцы нормальный оптимизатор осилить.

PD>Ох, не уверен. Ведь не одну strlen придется переписать, а весь string.h, если уж реализовать твою идею всерьез. А это обработка всех строк в С-коде, а это немалая часть этого кода, а этого кода тоже немало


Тоже фигня. Хочешь быстрой работы со строками забудь про string.h
Re[5]: Зачем нужны циклы если есть рекурсивные функции
От: LaptevVV Россия  
Дата: 30.09.09 13:26
Оценка: +1
Здравствуйте, gear nuke, Вы писали:

GN>А какая разница, как это реализуется, неужели от этого поменяется суть Впрочем, посмотрим, как...

GN>В последнем случает стек и для сохранения адреса возврата не используется. Да и что такое стек, адресуемая регистром общего назначения esp память? А почему именно esp, только потому, что в CISC x86 есть удобные команды для этого? Вот в самом первом примере стек значений от 5 до 0 реализован всего на одном регистре eax без посторонней памяти.
Не... Это не совсем регистр ОБЩЕГО назначения. Он является СПЕЦИАЛИЗИРОВАННЫМ регистром для указания именно вершины стека, поскольку и при выполнении команд CALL и ret, и при прерываниях (в частности в командах int xx и iret) его значение НЕЯВНО изменяется. Мы не можем задать ДРУГОЙ регистр, который вел бы себя аналогичным образом. И именно это неявное изменение и позволяет реализовать рекурсивные вызовы непосредственно на ассемблере. Таким образом, механизм поддержки рекурсии заложен непосредлственно в архитектуру.
То, что параметры при рекурсии складываются в стек, это необходимость для повторного входа. Но в архитектуре это не поддерживается и возлагается на программиста.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: Gluk_Kazan  
Дата: 30.09.09 13:57
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>>...потому что если цикл может быть реализован по регистру, рекурсия (если ее реализовать как положено) — это работа со стеком, то есть с памятью.

G>>Если рекурсию реализовать как положено, то она тоже прекратится в цикл в машинных кодах. Только не все компиляторы так умеют.

PD>Точнее сказать, никто не умеет. Потому что по calling convention, которые надо соблюдать, можно, конечно, аргументы передавать и через регистры, если их хватит, а вот адрес возврата всегда заносится в стек. По крайней мере в x86.


И gcc и MSVC давным давно умеют
Re[14]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 30.09.09 14:51
Оценка: 18 (1) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Сколько раз писал mov eax, 0 — ошибок, связанных с тем, что при этом меняется EIP — не было. Другие были


Вопрос в решаемых задачах.

GN>>Из известных примеров — Windows при обработке 2х байтного int 3.


PD>М.б. Я честно сказать, не в курсе — вроде он был однобайтный. Мне такое самому писать не доводилось.


здесь

PD>За нашу и вашу свободу!




GN>>При этом, в зависимости от размера my_subroutine, может быть сделан "автоматический" выбор — инлайн, или call.


PD>Ну и прекрасно. То же, что и с inline в С — то ли будет, то ли нет, в зависимости от опций и настроения компилятора и фазы Луны. Еще есть __forceinline


Это все подконтрольно на самом деле.

GN>>Либо есть второй вариант — загнать себя в рамки без макросов


PD>Зачем ?


Потому что макросы якобы не есть Дзен и ведут к Немерло

>>и писать всё как настоящий джедай руками


PD>В кодах ?


На чистом ассемблере.

GN>>В машкодах нет, но на этом уровне абстракции никто и не работает.


PD>Как это никто не работает ? Люди — да.


Ну вообще-то иногда работают, но очень редко

PD> А процессор так вроде именно на этом уровне и работает. А выясняли мы вроде вопрос о подпрограммах именно в машинном коде. С командой ret , точнее, с командой из таких-то байтов (под рукой их нет)


У меня в примере мнемоники

Кстати, о ret. Мнемоника у неё retn. MASM понимает ret и автоматом подставит retn 8 при 2х входных параметрах stdcall подпрограммы. Говоря другими словами, команда перегружена В случае proc MASM ведёт себя как компилятор, можно даже представить себе транслятор который пойдёт дальше и будет инлайнить Хотя вряд ли кто будет писать — можно на макросах делать.

PD>Не увиливай. Я ничего не говорил о вызове и размере. Может, конечно. Только вот если код встраивается вместо вызова — это просто встраивание кода, а не вызов.


Я дополняю условия задачи до разумных, подпрограмма без вызова никому не нужна. А куда её встроит гипотетический транслятор — 80% его пользователей даже и не заметят

PD>Scheme я не знаю и маргинальными языками не интересуюсь.


Хм. Ну... тогда следует читать "LISP". Кстати создавали его что бы записывать алгоритмы для ассемблера. СОвременные макросы являются его жалким наследием

PD> Можно пример из какого-нибудь известного большинству языка? Pascal, C, C++, Java, C#, Basic, Fortran ...


А к чему ограничиваться этим списком?

Ок, возмём С: setjmp, CreateFiber, atexit() да и вообще разные колбэки. В С++ добавляются try {} catch {} Но это конечно цветочки...

PD>Может. При условии, что в том языке/системе это принято. В свое время (Win16) была calling conention Pascal (слева направо, стек очищает вызываемая). Если кто-то сейчас решится ее использовать -это будет ничем не оправданный трюк.


Этот — да. И это не отменяет возможную полезность других. На ассемблере каждый... пишет как он хочет (как лучше для решения задачи). Всё это "как принято" должно изучаться и писаться на других языках. Иначе на ассемблере не научиться, и писать смысла тоже нет — разве что времени куча.

PD>Я так подозреваю, что Hello, World в твоем определении тоже рекурсивна


Это вызов API (с побочным эффектом).
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[6]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 30.09.09 14:51
Оценка: -1
Здравствуйте, LaptevVV, Вы писали:

LVV>Не... Это не совсем регистр ОБЩЕГО назначения.


Я говорю не о 80286, а о 32ти битном режиме. Он ничем не хуже EDX.

LVV> Он является СПЕЦИАЛИЗИРОВАННЫМ регистром для указания именно вершины стека, поскольку и при выполнении команд CALL и ret,


Не "поскольку", а "в случаях, когда используются".

LVV>и при прерываниях (в частности в командах int xx и iret) его значение НЕЯВНО изменяется.


Перывания — тогда уж аппаратные надо упоминать. В Windows прерывания обрабатываются в ядре, в другом стеке.

LVV> Мы не можем задать ДРУГОЙ регистр, который вел бы себя аналогичным образом.


Если не вызывать внешнее API — можем.

LVV> И именно это неявное изменение и позволяет реализовать рекурсивные вызовы непосредственно на ассемблере. Таким образом, механизм поддержки рекурсии заложен непосредлственно в архитектуру.


Не вижу связи. "Неявное" (то есть описанное в доке) изменение можно всегда заменить не более чем парой отдельных команд. Intel C++ так делает при вызове stdcall API

LVV>То, что параметры при рекурсии складываются в стек, это необходимость для повторного входа. Но в архитектуре это не поддерживается и возлагается на программиста.


Параметры при рекурсии могут передаваться в регистрах. Как в моих примерах. И если есть call — то же могут.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[20]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 30.09.09 14:59
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

G>>Тебе еще раз повторить про ущербность самого наличия функции strlen, которая проистекает от ущербности наследния C?

PD>Кто мне тут про общие принципы говорил ? Забудь про С и строки , и оставайся просто при общих принципах.
Ну давай.

PD>Есть набор байтов, заканчивающийся нулем, найти сколько там байтов до нуля. Абстрактно, никакие не строки.

Ну покажи хоть одну реальную структуру, кроме asciiz строк, которая так выглядит.

А вот если еще более общий случай рассмотерть, такой как список, у которого голова и хвост, то именно на таких структурах используется рекурсия.
Кстати asciiz строка и является таким списком:
если p — char*, то получение головы — *p, хвоста — p+1, пустой список *p == NULL.

PD>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

Ну покажи хоть один реальный пример, иначе анафеме предаем.
Re[27]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 30.09.09 15:05
Оценка: :))
Здравствуйте, FR, Вы писали:

PD>>Как насчет рекурсивности команды repne scas ?


FR>с этим к gear nuke


С этим довольно просто — в мануалах действие команд описано алголоподобным синтаксисом, осталось выбрать другой
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[12]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 30.09.09 15:20
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>Да, новой не является. Пример с ASCIIZ — широко известный из учебников частный случай. И, что странно — зная про ASCIIZ, люди продолжают писать первый вариант цикла обработки битов. Попробу найти хоть одного человека, кто напишет 2й (можно изменить условия задачи, что бы было решабельно на ЯВУ).


PD>Ну посмотри, например, ассемблерный код strlen. Зная про ASCIIZ, люди из MS тем не менее не стали реализовать тупой проход (зато простой и понятный! ах как хорошо понятный , а устроили работу с DWORDами, далеко не столь ясную, да еще и на ассемблере. Из чего следует, что не все так просто, как тебе кажется. Как минимум — надо померить и тот,и другой алгоритмы по скорости.


Эх забыл я что тут любят уводить разговор в сторону и купился. Ответа на мой вопрос нет. Лаконичного императивного описания 2го кода отсюда
Автор: gear nuke
Дата: 28.09.09
нет и не будет. Ну и не надо: отрицательный результат — тоже результат
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[6]: Зачем нужны поля в .Net?
От: EvilChild Ниоткуда  
Дата: 30.09.09 16:06
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Мда уж. Это действительно то, что будет во второй бете? А почему в System.Collections.Generic

На эти вопросы скорее AVK ответит чем я.
now playing: Ellectrica — X File (Boris Brejcha Remix)
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 30.09.09 20:45
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Да какая там гордость. Не требовалось просто, вот и все.


Это многое говорит о твоих задачах.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[7]: Зачем нужны поля в .Net?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 30.09.09 20:45
Оценка:
Здравствуйте, EvilChild, Вы писали:

_FR>>Мда уж. Это действительно то, что будет во второй бете? А почему в System.Collections.Generic

EC>На эти вопросы скорее AVK ответит чем я.

AVK только слышал про наличие System.Reactive в SL3 Toolkit. При чем тут System.Collections.Generic я вообще не в курсе. В beta 2 скорее всего ничего, кроме IObserver/IObservable не будет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[29]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 04:15
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>Нету под рукой исходников, но простая логика подсказывает что при поддержке такого количества платформ ассемблер отдыхает.


Неубедительно. Платформы разные, но и библиотеки тоже разные. Я не знаю Unix, но сомневаюсь, что код strcpy берется там из *.lib файла

PD>>>>Всегда применим, по крайней мере, пока речь идет о неуправляемом коде.


FR>>>Угу язык си придумали именно поэтому.


PD>>При чем тут C ? Асм-вставки есть, например, и на Delphi, я уж не говорю о подключении extern функций из DLL, написанных на асме — это практически в любом языке можно.


FR>При том что появление языка си как раз и затолкало ассемблер в ту очень узкую нишу в которой он сейчас находится.

FR>Про дельфи не надо, я уже потрохов VCL накушался, там ассемблер по бедности, не смогли борландовцы нормальный оптимизатор осилить.

Ассемблер был еще в Турбо Паскале.

PD>>Ох, не уверен. Ведь не одну strlen придется переписать, а весь string.h, если уж реализовать твою идею всерьез. А это обработка всех строк в С-коде, а это немалая часть этого кода, а этого кода тоже немало


FR>Тоже фигня. Хочешь быстрой работы со строками забудь про string.h


Наоборот. Это самый быстрый код. Быстрее, чем std::string. На эту тему в форуме C++ много было.
With best regards
Pavel Dvorkin
Re[15]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 04:32
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Сколько раз писал mov eax, 0 — ошибок, связанных с тем, что при этом меняется EIP — не было. Другие были


GN>Вопрос в решаемых задачах.


А можно пример, когда при mov eax, 0 я должен учитывать изменениие EIP ? Не просто помнить, а вот... если забуду про его изменение, то эта команда или следующая за ней неправильно (в любом смысле) сработает ?

GN>>>Из известных примеров — Windows при обработке 2х байтного int 3.


PD>>М.б. Я честно сказать, не в курсе — вроде он был однобайтный. Мне такое самому писать не доводилось.


GN>здесь


Спасибо.

PD>>За нашу и вашу свободу!


GN>


GN>>>При этом, в зависимости от размера my_subroutine, может быть сделан "автоматический" выбор — инлайн, или call.


PD>>Ну и прекрасно. То же, что и с inline в С — то ли будет, то ли нет, в зависимости от опций и настроения компилятора и фазы Луны. Еще есть __forceinline


GN>Это все подконтрольно на самом деле.


Относительно.

MSDN:

The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword.

GN>Потому что макросы якобы не есть Дзен и ведут к Немерло


Я убежденный атеист . Это раз. А в Немерло они вести не могут — когда они появились, его и в зародыше не было.

>>>и писать всё как настоящий джедай руками


PD>>В кодах ?


GN>На чистом ассемблере.


В кодах лучше


GN>Кстати, о ret. Мнемоника у неё retn. MASM понимает ret и автоматом подставит retn 8 при 2х входных параметрах stdcall подпрограммы. Говоря другими словами, команда перегружена В случае proc MASM ведёт себя как компилятор, можно даже представить себе транслятор который пойдёт дальше и будет инлайнить Хотя вряд ли кто будет писать — можно на макросах делать.


+1

PD>>Не увиливай. Я ничего не говорил о вызове и размере. Может, конечно. Только вот если код встраивается вместо вызова — это просто встраивание кода, а не вызов.


GN>Я дополняю условия задачи до разумных, подпрограмма без вызова никому не нужна. А куда её встроит гипотетический транслятор — 80% его пользователей даже и не заметят


Ну и пусть не заметят. Кому надо — заметит. Да и остальные тоже — им отладку вести-то надо ?

PD>>Scheme я не знаю и маргинальными языками не интересуюсь.


GN>Хм. Ну... тогда следует читать "LISP". Кстати создавали его что бы записывать алгоритмы для ассемблера. СОвременные макросы являются его жалким наследием


Можешь не соглашаться, но ИМХО это тоже маргинал. При всем моем уважении к нему и к пишущим на нем.

PD>> Можно пример из какого-нибудь известного большинству языка? Pascal, C, C++, Java, C#, Basic, Fortran ...


GN>А к чему ограничиваться этим списком?


А все же ? Я привел почти все "большие" языки. Думаю, 95 , если не 99% ПО написано на них. И если уж в них пример тебе найти не удается, а надо привлекать оставшиеся 1-5%, то это значит, что прием, мягко говоря, не слишком популярный.

GN>Ок, возмём С: setjmp, CreateFiber, atexit() да и вообще разные колбэки. В С++ добавляются try {} catch {} Но это конечно цветочки...


И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?

PD>>Может. При условии, что в том языке/системе это принято. В свое время (Win16) была calling conention Pascal (слева направо, стек очищает вызываемая). Если кто-то сейчас решится ее использовать -это будет ничем не оправданный трюк.


GN>Этот — да. И это не отменяет возможную полезность других. На ассемблере каждый... пишет как он хочет (как лучше для решения задачи).


Да бога ради, я согласен. Пока нет стыковки с модулями на ЯВУ.

> Всё это "как принято" должно изучаться и писаться на других языках.


Не получится.

>Иначе на ассемблере не научиться, и писать смысла тоже нет — разве что времени куча.


Смысл написания (для меня) чего-то на асме — ускорение некоего кода. И только. Хакерством я переболел давно.

PD>>Я так подозреваю, что Hello, World в твоем определении тоже рекурсивна


GN>Это вызов API (с побочным эффектом).


With best regards
Pavel Dvorkin
Re[13]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 04:36
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


GN>>>Да, новой не является. Пример с ASCIIZ — широко известный из учебников частный случай. И, что странно — зная про ASCIIZ, люди продолжают писать первый вариант цикла обработки битов. Попробу найти хоть одного человека, кто напишет 2й (можно изменить условия задачи, что бы было решабельно на ЯВУ).


PD>>Ну посмотри, например, ассемблерный код strlen. Зная про ASCIIZ, люди из MS тем не менее не стали реализовать тупой проход (зато простой и понятный! ах как хорошо понятный , а устроили работу с DWORDами, далеко не столь ясную, да еще и на ассемблере. Из чего следует, что не все так просто, как тебе кажется. Как минимум — надо померить и тот,и другой алгоритмы по скорости.


GN>Эх забыл я что тут любят уводить разговор в сторону и купился.


Тут и не такое любят

>Ответа на мой вопрос нет. Лаконичного императивного описания 2го кода отсюда
Автор: gear nuke
Дата: 28.09.09
нет и не будет. Ну и не надо: отрицательный результат — тоже результат


Смотреть весь тред лень, да и при одновременной дискуссии с тобой и FR я не всегда уже помню, кто из вас что сказал . Здесь я вопроса не вижу, только твое высказывание и мой ответ. Повтори, пожалуйста, вопрос.
With best regards
Pavel Dvorkin
Re[23]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 04:41
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Это многое говорит о твоих задачах.


Ты прав, как всегда . Не бывает сложных задач без рекурсии, ну не бывает, и все
With best regards
Pavel Dvorkin
Re[30]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 04:49
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Неубедительно. Платформы разные, но и библиотеки тоже разные. Я не знаю Unix, но сомневаюсь, что код strcpy берется там из *.lib файла


А какая разница откуда берется если транслируется из си.

PD>Ассемблер был еще в Турбо Паскале.


В те времена он везде был. Сейчас необходимости в нем нет.

PD>Наоборот. Это самый быстрый код. Быстрее, чем std::string. На эту тему в форуме C++ много было.


И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти. И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком.
Re[21]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 05:07
Оценка:
Здравствуйте, gandjustas, Вы писали:

PD>>Есть набор байтов, заканчивающийся нулем, найти сколько там байтов до нуля. Абстрактно, никакие не строки.

G>Ну покажи хоть одну реальную структуру, кроме asciiz строк, которая так выглядит.

Линейный список. Количество элементов неизвестно, последний элемент имеет .pNext == 0. Логически то же самое.
Строка в текстовом файле. Завершающий символ, правда, не один, а два — CR/LF.

G>А вот если еще более общий случай рассмотерть, такой как список, у которого голова и хвост, то именно на таких структурах используется рекурсия.


Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.

Кстати, в дотнете разве в классах коллекций для IList используется рекурсия для основных действий ? Нет. Вот тебе пример. Класс LinkedList


public LinkedListNode<T> Find(T value)
{
    LinkedListNode<T> head = this.head;
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    if (head != null)
    {
        if (value != null)
        {
            do
            {
                if (comparer.Equals(head.item, value))
                {
                    return head;
                }
                head = head.next;
            }
            while (head != this.head);
        }
        else
        {
            do
            {
                if (head.item == null)
                {
                    return head;
                }
                head = head.next;
            }
            while (head != this.head);
        }
    }
    return null;
}


А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали

G>Кстати asciiz строка и является таким списком:

G>если p — char*, то получение головы — *p, хвоста — p+1, пустой список *p == NULL.

PD>>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>Ну покажи хоть один реальный пример, иначе анафеме предаем.

Показал. Твой же пример
With best regards
Pavel Dvorkin
Re[31]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 05:16
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Неубедительно. Платформы разные, но и библиотеки тоже разные. Я не знаю Unix, но сомневаюсь, что код strcpy берется там из *.lib файла


FR>А какая разница откуда берется если транслируется из си.


А ты в этом уверен ? У тебя же исходников нет

PD>>Ассемблер был еще в Турбо Паскале.


FR>В те времена он везде был. Сейчас необходимости в нем нет.


Для кого нет, для кого есть

PD>>Наоборот. Это самый быстрый код. Быстрее, чем std::string. На эту тему в форуме C++ много было.


FR>И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти.


А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?

Это раз. А во-вторых, тебе не кажется, что ты слишком много голословных утверждений делаешь ? Приведи данные с измерением времени, из которых следует, что char* медленнее, чем нечто иное, пусть и не в С/C++, тогда и поговорим.

>И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком.


В огороде бузина, а в Киеве дядька.
With best regards
Pavel Dvorkin
Re[7]: Зачем нужны циклы если есть рекурсивные функции
От: LaptevVV Россия  
Дата: 01.10.09 05:26
Оценка: +1
Здравствуйте, gear nuke, Вы писали:

LVV>>Не... Это не совсем регистр ОБЩЕГО назначения.

GN>Я говорю не о 80286, а о 32ти битном режиме. Он ничем не хуже EDX.
Я тоже. Но EDX не изменяется автоматически при выполнении команды CALL, a ESP — изменяется.
LVV>> Он является СПЕЦИАЛИЗИРОВАННЫМ регистром для указания именно вершины стека, поскольку и при выполнении команд CALL и ret,
GN>Не "поскольку", а "в случаях, когда используются".
А используется он как раз при обращении к стеку — во всех стековых командах, при вызове подпрограмме и возврате из нее, при прерываниях и возврате из него.
LVV>> Мы не можем задать ДРУГОЙ регистр, который вел бы себя аналогичным образом.
GN>Если не вызывать внешнее API — можем.
Нет. Похожим образом АВТОМАТИЧЕСКИ ведут себя еще индексные регистры. Но при использовании остальных мы должны ЯВНО программировать поведение.
LVV>> И именно это неявное изменение и позволяет реализовать рекурсивные вызовы непосредственно на ассемблере. Таким образом, механизм поддержки рекурсии заложен непосредственно в архитектуру.
GN>Не вижу связи. "Неявное" (то есть описанное в доке) изменение можно всегда заменить не более чем парой отдельных команд. Intel C++ так делает при вызове stdcall API
Промоделировать. естественно, можно все. На машине без стека вполне можно выделить один регистр для этого дела и моделировать стек — нефиг делать. Но это означает, что в архитектуре отсутствуют некоторые возможности.
LVV>>То, что параметры при рекурсии складываются в стек, это необходимость для повторного входа. Но в архитектуре это не поддерживается и возлагается на программиста.
GN>Параметры при рекурсии могут передаваться в регистрах. Как в моих примерах. И если есть call — то же могут.
Только при этом придется моделировать стек в виде сохранения предыдущих значений переменных.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[32]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 05:38
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А ты в этом уверен ? У тебя же исходников нет


Да мне пофиг


PD>Для кого нет, для кого есть


Тогда он был необходим, сейчас нет, это очень большая разница.

FR>>И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти.


PD>А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?


То что в других системах тоже надо выделять память никак ни отменяет того факта что для std::string это сделано бездарно.
Ну и даже в C++ на типичных задачах парсинга можно почти полностью обходится без выделения памяти, срезы рулят.

PD>Это раз. А во-вторых, тебе не кажется, что ты слишком много голословных утверждений делаешь ? Приведи данные с измерением времени, из которых следует, что char* медленнее, чем нечто иное, пусть и не в С/C++, тогда и поговорим.


Я писал парсеры на C++. Использовал срезы типа этих http://rsdn.ru/forum/src/2287365.1.aspx
Автор: c-smile
Дата: 02.01.07
, до этого были два не мной написанных варианта сначала на std::string, потом ускорили этот вариант переписав часть алгоритмов практически на чистый си. Я писал заново сразу на срезах ускорение на больших файлах почти в 10 раз.
Данные привести не могу, писать заново тесты интереса нет.
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.10.09 05:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, gandjustas, Вы писали:


PD>>>Есть набор байтов, заканчивающийся нулем, найти сколько там байтов до нуля. Абстрактно, никакие не строки.

G>>Ну покажи хоть одну реальную структуру, кроме asciiz строк, которая так выглядит.

PD>Линейный список. Количество элементов неизвестно, последний элемент имеет .pNext == 0. Логически то же самое.

Да, но это уже не последовательность байтов, а следовательно супер-пупер оптимизированный ассемблерный вариант, типа strlen не подойдет.

PD>Строка в текстовом файле. Завершающий символ, правда, не один, а два — CR/LF.

Ну опять вернулись к строкам...

G>>А вот если еще более общий случай рассмотерть, такой как список, у которого голова и хвост, то именно на таких структурах используется рекурсия.

PD>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.
Ты уже забыл что даже компиляторы C умеют оптимизировать хвостовую рекурсию?

PD>Кстати, в дотнете разве в классах коллекций для IList используется рекурсия для основных действий ? Нет. Вот тебе пример. Класс LinkedList

PD>А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали
Потому что в компиляторе C# оптимизации хвостовой рекурсии нет.
Вот в F# есть, там многие операции так реализованы.

G>>Кстати asciiz строка и является таким списком:

G>>если p — char*, то получение головы — *p, хвоста — p+1, пустой список *p == NULL.

PD>>>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>>Ну покажи хоть один реальный пример, иначе анафеме предаем.
PD>Показал. Твой же пример
Какой?
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 05:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А можно пример, когда при mov eax, 0 я должен учитывать изменениие EIP ? Не просто помнить, а вот... если забуду про его изменение, то эта команда или следующая за ней неправильно (в любом смысле) сработает ?


Модификация кода во время выполнения. Да вот свежий пример. Ладно бы только в таком контексте втстречалось... Проблема настолько серьёзна, что MS придумали hotpatchable images. Кстати решается на любом языке имеющем interlocked операции, или способном вызывать WinAPI.

PD>MSDN:


PD>The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword.


Случаи, когда __forceinline не будет работать (например, когда есть взятие адреса функции) описаны в том же MSDN.

PD>Я убежденный атеист .


Атеизм — всего лишь другая вера.

PD>И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?


Да, в том-то и дело, что это не трюки Почему же это трюки когда речь идёт об асме

GN>>Этот — да. И это не отменяет возможную полезность других. На ассемблере каждый... пишет как он хочет (как лучше для решения задачи).


PD>Да бога ради, я согласен. Пока нет стыковки с модулями на ЯВУ.


Это говорит лишь об ограниченности взгляда на реальное положение вещей. Сейчас асм используется разве что в малваре, а там API может запросто вызываться через хитрый переходник, который найдёт экспорт по хешу имени, достанет через задницу откуда-то параметры, поксорит дворды и вызовет функцию посредством retn. Потому что авторы знают — аналитик, изучавший ассемблер на примере masm'овского while — будет смотреть на код как баран на новые ворота.

>> Всё это "как принято" должно изучаться и писаться на других языках.


PD>Не получится.


Хм. Ну... я могу привести пример, что нельзя сделать в рамках С++ и придётся использовать ассемблер — зарегистрировать хендлер как safeseh в таблице PE. Какие есть еще варианты?

>>Иначе на ассемблере не научиться, и писать смысла тоже нет — разве что времени куча.


PD>Смысл написания (для меня) чего-то на асме — ускорение некоего кода. И только. Хакерством я переболел давно.


В 99% случаев это бесполезная трата времени. Пока счёт 1:0
Автор: gear nuke
Дата: 30.09.09
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[14]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 05:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Смотреть весь тред лень, да и при одновременной дискуссии с тобой и FR я не всегда уже помню, кто из вас что сказал . Здесь я вопроса не вижу, только твое высказывание и мой ответ. Повтори, пожалуйста, вопрос.


Прошу прощения, забыл про почтовых клиентов

Есть 32 бита в регистре (не конь в вуккуме, а, например, маска пикселей) нужно их как-то обработать по-одному. Как будет решаться задача императивно, циклом? В лоб:
    mov eax, [pixels]  
    mov ecx, 32  
@@: shr eax, 1  ; копируем очередной бит в Carry Flag
    ;
    ; тут что-то делаем с битом
    ;
    dec ecx  ; итерируем цикл
    jnz @b

Если немного подумать, то на ассемблере это делается так:
    mov eax, [pixels]
    stc    ; используем Carry Flag как "маркер" конца битовой последовательности.
@@: rcr eax, 1 ; копируем очередной бит в Carry Flag. за счёт цикличности сдвига, меркер перейдёт в младший бит на первом проходе.
    ;
    ; тут что-то делаем с битом
    ;
    or  eax, eax  ; проверяем, остался ли бит маркера.
    jnz @b

Счётчик цикла убран за не надобностью тратить лишний регистр. Как бы так "императивно" объяснить вышепроисходящее, без упоминаний о битах? С другой стороны, можно сказать что здесь рекурсивный вызов, где параметром передаётся "остаток" последовательности.

Если есть возможность — попробуйте провести экспеимент на студентах, как много способны написать 2й вариант. Можно даже на ЯВУ, если изменить условия задачи. Мой прогноз: без подсказок — 0.1%. Со strlen на самом деле мало общего.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[33]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:01
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А ты в этом уверен ? У тебя же исходников нет


FR>Да мне пофиг





PD>>Для кого нет, для кого есть


FR>Тогда он был необходим, сейчас нет, это очень большая разница.


Для кого необходим, а для кого и нет

FR>>>И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти.


PD>>А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?


FR>То что в других системах тоже надо выделять память никак ни отменяет того факта что для std::string это сделано бездарно.


Согласен. Но я его и не использую. Мне char* хватит. Он не сделан бездарно

FR>Ну и даже в C++ на типичных задачах парсинга можно почти полностью обходится без выделения памяти, срезы рулят.


Я и не для парсинга обхожусь .

PD>>Это раз. А во-вторых, тебе не кажется, что ты слишком много голословных утверждений делаешь ? Приведи данные с измерением времени, из которых следует, что char* медленнее, чем нечто иное, пусть и не в С/C++, тогда и поговорим.


FR>Я писал парсеры на C++. Использовал срезы типа этих http://rsdn.ru/forum/src/2287365.1.aspx
Автор: c-smile
Дата: 02.01.07
, до этого были два не мной написанных варианта сначала на std::string, потом ускорили этот вариант переписав часть алгоритмов практически на чистый си. Я писал заново сразу на срезах ускорение на больших файлах почти в 10 раз.


Я что-то не понял, что ты этим хочешь сказать ? Что std::string барахло ? Согласен. Что можно сделать умнее, чем просто аллоцировать новую строку каждый раз, когда она нужна ? Тоже согласен. Есть еще, кстати, strtok, она как раз делит строку на фрагменты без выделения новой памяти вообще, правда, портит исходную строку. Но какое это отношение имеет к твоему утверждению, что ASCIIZ очень медленный ?


Не надо открывать Америки. strtok — почти та же идея.


FR>Данные привести не могу, писать заново тесты интереса нет.
With best regards
Pavel Dvorkin
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 06:05
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


PD>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.


Вся функциональщина живет на рекурсивных алгоритмах на линейных списках, стек при этом никуда не дергается.


PD>А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали


Если язык и рантайм позволяют то организуют:

let rec find p = function
  | [] -> raise Not_found
  | x :: l -> if p x then x else find p l




_camlFind000__find_59:
    subl    $12, %esp
L102:
    movl    %eax, %edx
    cmpl    $1, %ebx
    je    L100
    movl    %ebx, 0(%esp)
    movl    %edx, 4(%esp)
    movl    (%ebx), %eax
    movl    %eax, 8(%esp)
    movl    (%edx), %ecx
    movl    %edx, %ebx
    call    *%ecx
L103:
    cmpl    $1, %eax
    je    L101
    movl    8(%esp), %eax
    addl    $12, %esp
    ret
    .align    16
L101:
    movl    0(%esp), %eax
    movl    4(%eax), %ebx
    movl    4(%esp), %eax
    jmp    L102
    .align    16
L100:
L104:    movl    _caml_young_ptr, %eax
    subl    $8, %eax
    movl    %eax, _caml_young_ptr
    cmpl    _caml_young_limit, %eax
    jb    L105
    leal    4(%eax), %eax
    movl    $1024, -4(%eax)
    movl    $_caml_exn_Not_found, (%eax)
    movl    _caml_exception_pointer, %esp
    popl    _caml_exception_pointer
    ret
L105:    call    _caml_call_gc
L106:    jmp    L104
    .text
    .align    16
    .globl    _camlFind000__fun_72
_camlFind000__fun_72:
L107:
    pushl    %ebx
    pushl    %eax
    movl    $_caml_equal, %eax
    call    _caml_c_call
L108:
    addl    $8, %esp
    ret
Re[17]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:21
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А можно пример, когда при mov eax, 0 я должен учитывать изменениие EIP ? Не просто помнить, а вот... если забуду про его изменение, то эта команда или следующая за ней неправильно (в любом смысле) сработает ?


GN>Модификация кода во время выполнения.


Ну я же говорю, что тебя трюки в основном и привлекают



PD>>MSDN:


PD>>The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword.


PD>>Я убежденный атеист .


GN>Атеизм — всего лишь другая вера.


Это в СВ

PD>>И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?


GN>Да, в том-то и дело, что это не трюки Почему же это трюки когда речь идёт об асме


Ей-богу, ничего не понял.

GN>>>Этот — да. И это не отменяет возможную полезность других. На ассемблере каждый... пишет как он хочет (как лучше для решения задачи).


PD>>Да бога ради, я согласен. Пока нет стыковки с модулями на ЯВУ.


GN>Это говорит лишь об ограниченности взгляда на реальное положение вещей. Сейчас асм используется разве что в малваре, а там API может запросто вызываться через хитрый переходник, который найдёт экспорт по хешу имени, достанет через задницу откуда-то параметры, поксорит дворды и вызовет функцию посредством retn. Потому что авторы знают — аналитик, изучавший ассемблер на примере masm'овского while — будет смотреть на код как баран на новые ворота.





GN>Хм. Ну... я могу привести пример, что нельзя сделать в рамках С++ и придётся использовать ассемблер — зарегистрировать хендлер как safeseh в таблице PE.


Хм, а почему это нельзя ? Указатели вроде не отменили, запись по ним тоже.

>Какие есть еще варианты?


Скорость. Остальное меня мало интересует. Я не исследую малваре, а поэтому не буду искать переходники по хешу, доставть параметры из ... , ксорить дворды и вызывать функцию посредством ret . Я предпочту созерцать новые ворота вместо этого . А вот скорость меня интересует, когда ее можно улучшить.

>>>Иначе на ассемблере не научиться, и писать смысла тоже нет — разве что времени куча.


PD>>Смысл написания (для меня) чего-то на асме — ускорение некоего кода. И только. Хакерством я переболел давно.


GN>В 99% случаев это бесполезная трата времени. Пока счёт 1:0
Автор: gear nuke
Дата: 30.09.09


Ну и аргумент. Ты хоть посмотри, что __readfsdword делает. Это же встраивание машинных команд и есть
With best regards
Pavel Dvorkin
Re[32]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 01.10.09 06:23
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?


Вопрос во-первых, в том, сколько динамической памяти выделяется. Выделить подстроку можно, например, выделяя константное кол-во памяти, а не линейное. И результат конкатенации строк длинной N и K можно получить выделяя константное или логарифмическое кол-во памяти, а не N+K.
А во-вторых в том, что выделение памяти в разных менеджерах памяти будет стоить разного времени.

>>И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком.

PD>В огороде бузина, а в Киеве дядька.

Да нет, намек достаточно прозрачен. Есть мнение, что асимптотика алгоритма имеет значение. И при больших N как не оптимизируй, но вычисление длинны за линейное время не обгонит вычисление длинны за время константное.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[34]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 06:23
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Согласен. Но я его и не использую. Мне char* хватит. Он не сделан бездарно


Тоже ничего хорошего

PD>Я что-то не понял, что ты этим хочешь сказать ? Что std::string барахло ? Согласен. Что можно сделать умнее, чем просто аллоцировать новую строку каждый раз, когда она нужна ? Тоже согласен. Есть еще, кстати, strtok, она как раз делит строку на фрагменты без выделения новой памяти вообще, правда, портит исходную строку. Но какое это отношение имеет к твоему утверждению, что ASCIIZ очень медленный ?


Такое что даже переписанные на ASCIIZ алгоритмы (второй вариант) были на порядок тормознее чем срезы.

PD>Не надо открывать Америки. strtok — почти та же идея.


Нет это совсем другое.
Re[8]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 06:24
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>>>Не... Это не совсем регистр ОБЩЕГО назначения.

GN>>Я говорю не о 80286, а о 32ти битном режиме. Он ничем не хуже EDX.
LVV>Я тоже. Но EDX не изменяется автоматически при выполнении команды CALL, a ESP — изменяется.

Intel Architecture Software Developer's Manual, Volume 1: Basic Architecture

3.6.1. General-Purpose Data Registers
The 32-bit general-purpose data registers EAX, EBX, ECX, EDX, ESI, EDI, EBP, and ESP are
provided for holding the following items:
• Operands for logical and arithmetic operations
• Operands for address calculations
• Memory pointers
Although all of these registers are available for general storage of operands, results, and
pointers, caution should be used when referencing the ESP register. The ESP register holds the
stack pointer and as a general rule should not be used for any other purpose.


LVV>>> Он является СПЕЦИАЛИЗИРОВАННЫМ регистром для указания именно вершины стека, поскольку и при выполнении команд CALL и ret,

GN>>Не "поскольку", а "в случаях, когда используются".
LVV>А используется он как раз при обращении к стеку — во всех стековых командах, при вызове подпрограмме и возврате из нее, при прерываниях и возврате из него.

Используется оно когда захочет автор.

LVV>>> Мы не можем задать ДРУГОЙ регистр, который вел бы себя аналогичным образом.

GN>>Если не вызывать внешнее API — можем.
LVV>Нет. Похожим образом АВТОМАТИЧЕСКИ ведут себя еще индексные регистры. Но при использовании остальных мы должны ЯВНО программировать поведение.

It is possible, in some cases, to temporarily reuse ESP as a general purpose register. Since the x86 architecture is so register-starved, adding an eighth register can eliminate the need to spill variables to memory and boost the speed of a critical inner loop. I've used this in a couple of places in VirtualDub when I really needed it, and some have asked if it is actually safe to do this. The answer is yes...

здесь

GN>>Параметры при рекурсии могут передаваться в регистрах. Как в моих примерах. И если есть call — то же могут.

LVV>Только при этом придется моделировать стек в виде сохранения предыдущих значений переменных.

"Стек значений" от eax до нуля:
f:  dec eax
    jz @f
    call f
@@: retn
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[18]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 06:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>Модификация кода во время выполнения.


PD>Ну я же говорю, что тебя трюки в основном и привлекают


Мне лишь приходится с этим иметь дело. Желающих пропатчить код Винды сейчас пруд пруди.

PD>>>И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?


GN>>Да, в том-то и дело, что это не трюки Почему же это трюки когда речь идёт об асме


PD>Ей-богу, ничего не понял.


Континуации на асме были названы трюками. А на С — обычным делом С первым я и не согласен.

GN>>Хм. Ну... я могу привести пример, что нельзя сделать в рамках С++ и придётся использовать ассемблер — зарегистрировать хендлер как safeseh в таблице PE.


PD>Хм, а почему это нельзя ? Указатели вроде не отменили, запись по ним тоже.


Это процесс времени трансляции. Компилятор С++ помещает нужную информацию в объектник не для всех случаев. Решается линковкой оттранслированного асм файла (не содержащего кстати ни одной мнемоники)

PD>Ну и аргумент. Ты хоть посмотри, что __readfsdword делает. Это же встраивание машинных команд и есть


Многие другие конструкции С++ приводят к встраиванию команд, об этом и речь, что нет нужды писать их руками.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[15]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:48
Оценка:
Здравствуйте, gear nuke, Вы писали:


GN>Есть 32 бита в регистре (не конь в вуккуме, а, например, маска пикселей) нужно их как-то обработать по-одному. Как будет решаться задача императивно, циклом? В лоб:

GN>
GN>    mov eax, [pixels]  
GN>    mov ecx, 32  
GN>@@: shr eax, 1  ; копируем очередной бит в Carry Flag
GN>    ;
GN>    ; тут что-то делаем с битом
GN>    ;
GN>    dec ecx  ; итерируем цикл
GN>    jnz @b
GN>

GN>Если немного подумать, то на ассемблере это делается так:
GN>
GN>    mov eax, [pixels]
GN>    stc    ; используем Carry Flag как "маркер" конца битовой последовательности.
GN>@@: rcr eax, 1 ; копируем очередной бит в Carry Flag. за счёт цикличности сдвига, меркер перейдёт в младший бит на первом проходе.
GN>    ;
GN>    ; тут что-то делаем с битом
GN>    ;
GN>    or  eax, eax  ; проверяем, остался ли бит маркера.
GN>    jnz @b
GN>

GN>Счётчик цикла убран за не надобностью тратить лишний регистр. Как бы так "императивно" объяснить вышепроисходящее, без упоминаний о битах?

Двумя словами — проход с барьером. Если хочешь пример аналога без битов — проход циклического списка с псевдоначалом (неким выбранным элементом, с которого стартуем и который содержит, скажем, NULL в поле данных). Другое дело, что это лишнее, проход и без этого "маркера" можно провести.

Или ты что-то другое хочешь ? Но твою задачу как она есть я без упоминаний о битах не могу объяснить, коль скоро там именно биты.

>С другой стороны, можно сказать что здесь рекурсивный вызов, где параметром передаётся "остаток" последовательности.


Поиск льва в Африке помнишь ?

New programmer : Двигаясь от Кейптауна к Каиру и при этом с запада на восток и с востока на запад, ловит первое попавшееся животное и сравнивает его с известным львом.
Advanced programmer : То же, но предварительно помещает льва в зоопарк в Каире , чтобы поиск гарантированно окончился



GN>Если есть возможность — попробуйте провести экспеимент на студентах, как много способны написать 2й вариант. Можно даже на ЯВУ, если изменить условия задачи. Мой прогноз: без подсказок — 0.1%. Со strlen на самом деле мало общего.


Не так уж мало. И там и тут проход с барьером. Только ты (и я в варианте со списком) этот барьер заносишь явно, а для char* его занесли до нас.
With best regards
Pavel Dvorkin
Re[23]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

PD>>Линейный список. Количество элементов неизвестно, последний элемент имеет .pNext == 0. Логически то же самое.

G>Да, но это уже не последовательность байтов

Кто мне про общие принципы толковал ? Общий принцип тут один и тот же — структура с терминатором.

>а следовательно супер-пупер оптимизированный ассемблерный вариант, типа strlen не подойдет.


То тебе подай хоть одну еще такую же структуру. Дал — теперь она тебя не устраивает по совсем другим причинам. Я что, так и буду на все твои новые возражения из другой оперы отвечать ?


PD>>Строка в текстовом файле. Завершающий символ, правда, не один, а два — CR/LF.

G>Ну опять вернулись к строкам...

А ты предложи заменить текстовые файлы на что-то иное. Например, хранить длину каждой строки перед самой строкой

PD>>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.

G>Ты уже забыл что даже компиляторы C умеют оптимизировать хвостовую рекурсию?

Упаси меня бог от рекурсии на списках, как хвостовой, так и безхвостой, как оптимизированной, так и нет.

PD>>Кстати, в дотнете разве в классах коллекций для IList используется рекурсия для основных действий ? Нет. Вот тебе пример. Класс LinkedList

PD>>А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали
G>Потому что в компиляторе C# оптимизации хвостовой рекурсии нет.

Слава богу.

G>Вот в F# есть, там многие операции так реализованы.


Ну и прекрасно. Подождем появления G#, может , там и бесхвостую соптимизируют

PD>>>>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>>>Ну покажи хоть один реальный пример, иначе анафеме предаем.
PD>>Показал. Твой же пример
G>Какой?

Список.

Все, закончил. Иначе этому конца не будет. За тобой право последнего ответа
With best regards
Pavel Dvorkin
Re[24]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.10.09 07:05
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, gandjustas, Вы писали:


PD>>>Линейный список. Количество элементов неизвестно, последний элемент имеет .pNext == 0. Логически то же самое.

G>>Да, но это уже не последовательность байтов

PD>Кто мне про общие принципы толковал ? Общий принцип тут один и тот же — структура с терминатором.

Ну так это и есть тот самый список, который чаще всего рекусривно обрабатывается.
Читай SICP.

PD>>>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.

G>>Ты уже забыл что даже компиляторы C умеют оптимизировать хвостовую рекурсию?
PD>Упаси меня бог от рекурсии на списках, как хвостовой, так и безхвостой, как оптимизированной, так и нет.
Ну и что ты имеешь против рекурсии?


PD>>>Кстати, в дотнете разве в классах коллекций для IList используется рекурсия для основных действий ? Нет. Вот тебе пример. Класс LinkedList

PD>>>А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали
G>>Потому что в компиляторе C# оптимизации хвостовой рекурсии нет.
PD>Слава богу.
Темная сторона силы владеет тобой, о юный падаван.


PD>>>>>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>>>>Ну покажи хоть один реальный пример, иначе анафеме предаем.
PD>>>Показал. Твой же пример
G>>Какой?
PD>Список.
Читай SICP, там две трети про списки и обработку их с помощью рекурсии.
Re[23]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 07:06
Оценка: -3 :)))
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:



PD>>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.


FR>Вся функциональщина живет на рекурсивных алгоритмах на линейных списках, стек при этом никуда не дергается.


А я живу без функциональщины. Мне и так хорошо
With best regards
Pavel Dvorkin
Re[35]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 07:12
Оценка:
Здравствуйте, FR, Вы писали:


PD>>Согласен. Но я его и не использую. Мне char* хватит. Он не сделан бездарно


FR>Тоже ничего хорошего


Доказательства в студию!

PD>>Я что-то не понял, что ты этим хочешь сказать ? Что std::string барахло ? Согласен. Что можно сделать умнее, чем просто аллоцировать новую строку каждый раз, когда она нужна ? Тоже согласен. Есть еще, кстати, strtok, она как раз делит строку на фрагменты без выделения новой памяти вообще, правда, портит исходную строку. Но какое это отношение имеет к твоему утверждению, что ASCIIZ очень медленный ?


FR>Такое что даже переписанные на ASCIIZ алгоритмы (второй вариант) были на порядок тормознее чем срезы.


Батенька, ну нельзя же так! Срезы — это некая иная идея. Строки она не отменяет, просто для определенных задач она позволяет более эффективно работать. В других случаях они просто неприменимы. Из того, что что-то частное можно организовать лучше, вовсе не следует. что это частное можно использовать в общем случае.

>В функциях текстовой обработки или поиска достаточно часто требуется вернуть фрагмент подстроки.


А если мне модифицировать строки надо, да еще с изменением длины, когда inplace нельзя, а фрагменты эти даром не нужны — тогда как ?
With best regards
Pavel Dvorkin
Re[19]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 07:18
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


GN>>>Модификация кода во время выполнения.


PD>>Ну я же говорю, что тебя трюки в основном и привлекают


GN>Мне лишь приходится с этим иметь дело. Желающих пропатчить код Винды сейчас пруд пруди.


Успехов! Я серьезно.

GN>Континуации на асме были названы трюками. А на С — обычным делом С первым я и не согласен.


Ладно, пусть так. В конце концов при желании можно любой код назвать континуацией

PD>>Хм, а почему это нельзя ? Указатели вроде не отменили, запись по ним тоже.


GN>Это процесс времени трансляции. Компилятор С++ помещает нужную информацию в объектник не для всех случаев. Решается линковкой оттранслированного асм файла (не содержащего кстати ни одной мнемоники)


Ничего не понял. Как это асм файл можно линковать ???


GN>Многие другие конструкции С++ приводят к встраиванию команд


Очень многие. Все, кроме декларативных


>об этом и речь, что нет нужды писать их руками.


Если хорошо встраивает — тогда да. А если не очень — то нет.

Кстати, насчет твоей GetSeperMegaFastThreadID. Проверял, быстрее. А вот счет 1:0 не признаю. Ты же алгоритм изменил. Твой быстрее, верно, но при чем тут ассемблер ?
With best regards
Pavel Dvorkin
Re[36]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 07:20
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

FR>>Тоже ничего хорошего


PD>Доказательства в студию!


http://russian.joelonsoftware.com/Articles/BacktoBasics.html

FR>>Такое что даже переписанные на ASCIIZ алгоритмы (второй вариант) были на порядок тормознее чем срезы.


PD>Батенька, ну нельзя же так! Срезы — это некая иная идея. Строки она не отменяет, просто для определенных задач она позволяет более эффективно работать. В других случаях они просто неприменимы. Из того, что что-то частное можно организовать лучше, вовсе не следует. что это частное можно использовать в общем случае.


А в других случаях ASCIIZ практически всегда сливают, например для строк с счетчиком длины.

>>В функциях текстовой обработки или поиска достаточно часто требуется вернуть фрагмент подстроки.


PD>А если мне модифицировать строки надо, да еще с изменением длины, когда inplace нельзя, а фрагменты эти даром не нужны — тогда как ?


Тогда конечно только вручную на ассемблере
Re[33]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 07:26
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Вопрос во-первых, в том, сколько динамической памяти выделяется. Выделить подстроку можно, например, выделяя константное кол-во памяти, а не линейное.


Можно насчет значения константы поинтересоваться и о том, что делать, если истинная длина строки больше ее ?

>>>И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком.

PD>>В огороде бузина, а в Киеве дядька.

K>Да нет, намек достаточно прозрачен. Есть мнение, что асимптотика алгоритма имеет значение.

>И при больших N как не оптимизируй, но вычисление длинны за линейное время не обгонит вычисление длинны за время константное.

Это верно почти всегда, только надо иметь в виду, что а) вычисление длины за константное время невозможно, если кто-то ее до этого не вычислил и не положил куда следует, причем вычислил за линейное время и б) в ряде случаев можно потратить на вычисление длины нулевое время, потому как она совсем не нужна
With best regards
Pavel Dvorkin
Re[34]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 01.10.09 07:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

K>>Вопрос во-первых, в том, сколько динамической памяти выделяется. Выделить подстроку можно, например, выделяя константное кол-во памяти, а не линейное.

PD>Можно насчет значения константы поинтересоваться и о том, что делать, если истинная длина строки больше ее ?

Значение этой константы — размер двух указателей на границы интервала (или двух индексов), или размер одного узла дерева и т.д. Зависит от структуры данных. И длинна строки, разумеется, занчительно больше.

PD>Это верно почти всегда,


Вот именно.

PD> только надо иметь в виду, что а) вычисление длины за константное время невозможно, если кто-то ее до этого не вычислил и не положил куда следует, причем вычислил за линейное время


Один раз (во время компиляции или чтения из файла, например), а не много раз, как в случае, когда размер не хранится вместе со строкой.

PD>б) в ряде случаев можно потратить на вычисление длины нулевое время, потому как она совсем не нужна


Это существенного значения не имеет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 07:41
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>
GN>>    mov eax, [pixels]
GN>>    stc    ; используем Carry Flag как "маркер" конца битовой последовательности.
GN>>@@: rcr eax, 1 ; копируем очередной бит в Carry Flag. за счёт цикличности сдвига, меркер перейдёт в младший бит на первом проходе.
GN>>    ;
GN>>    ; тут что-то делаем с битом
GN>>    ;
GN>>    or  eax, eax  ; проверяем, остался ли бит маркера.
GN>>    jnz @b
GN>>


PD>Двумя словами — проход с барьером. Если хочешь пример аналога без битов — проход циклического списка с псевдоначалом (неким выбранным элементом, с которого стартуем и который содержит, скажем, NULL в поле данных).


То что я называю маркером, имеет значение совпадающее с возможным для данных.

PD>Другое дело, что это лишнее, проход и без этого "маркера" можно провести.


Можно, но потребует дополнительных ресурсов.

PD>Не так уж мало. И там и тут проход с барьером. Только ты (и я в варианте со списком) этот барьер заносишь явно, а для char* его занесли до нас.


Аналогом могла бы служить последовательность только из байтов 0 и 1.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[20]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 07:41
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>Это процесс времени трансляции. Компилятор С++ помещает нужную информацию в объектник не для всех случаев. Решается линковкой оттранслированного асм файла (не содержащего кстати ни одной мнемоники)


PD>Ничего не понял. Как это асм файл можно линковать ???


Имеется ввиду объектник.

PD>Кстати, насчет твоей GetSeperMegaFastThreadID. Проверял, быстрее. А вот счет 1:0 не признаю. Ты же алгоритм изменил. Твой быстрее, верно, но при чем тут ассемблер ?


Вот я к тому и веду — что от ассемблера мало что зависит
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[25]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 07:43
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Темная сторона силы владеет тобой, о юный падаван.


Эх, где моя юность . Попался бы ты мне в юные года, я бы тебе не такое сказал
With best regards
Pavel Dvorkin
Re[37]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 08:07
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:


FR>>>Тоже ничего хорошего


PD>>Доказательства в студию!


FR>http://russian.joelonsoftware.com/Articles/BacktoBasics.html


Да уж. Пример с strcat — классический способ демонстрации того, как даже с помощью наилучшего инструмента можно все испортить. Глупостями заниматься нечего.

>Как с этим бороться? Многие хитрые программисты на C написали свою функцию mystrcat примерно так:


И я писал, но немного не так. Код не приведу, а прототип дам

static int ConcatenateStrings(char* pWriteTo, char* szString, ... );

Ну все. Сейчас флейм на тему переменного числа параметров начнется

>Глаза б мои не видели. Вы, наверное, уже готовы переключить канал. Я понимаю, но подождите ещё чуть-чуть, потому что сейчас будет самое интересное. Нам нужно пройти по всем строкам раз, чтобы определить, сколько места выделить, и затем ещё раз, чтобы их соединить


Мои бы тоже. Мне бы ваши проблемы. А уж дальше про работу кучи — вообще прелесть.

>Соответственно malloc объявляет перерыв и начинает перетряхивать список свободных блоков, сливая соседние маленькие блоки воедино, на что уходит три с половиной дня.


Супер! Мозги ему перетряхнуть надо, чтобы чушь не писал.
Кстати, интересно, знает ли он, что кроме кучи кое-что еще есть ?

И такими аргументами ты хочешь меня в чем-то убедить ?

FR>А в других случаях ASCIIZ практически всегда сливают, например для строк с счетчиком длины.


А длину святой дух установил ? Или ее все же подсчитали когда-то путем все-таки линейного прохода ? Потому что другого способа все же нет (хотя, конечно, вычисление длины могло бы быть побочным результатом того же копирования). Если хочешь сказать, что ее подсчитали один раз, а потом не пересчитывали, а мне придется каждый раз — немедленно соглашусь. Но если она мне нужна много раз — кто мне мешает тоже ее один раз вычислить и хранить ? А вот если она мне совсем не нужна, то ты пустую работу по ее вычислению делаешь.

Если короче — я привесить длину к char* могу без труда, если надо, а вот ты убрать ее из своего класса не можешь — никак

А вот что да — так это то, что в string.h не все идеально. Например,

char *strcpy(
char *strDestination,
const char *strSource
);
Each of these functions returns the destination string

Единственное, что ИМХО оправдывает этот возврат — возможность вложенных вызовов. Но это экзотика, да и без них можно обычно обойтись. Я бы вместо того, чтобы возвращать destination, вернул бы указатель на '\0' в этом destination. И целым рядом проблем меньше.

Кстати

int sprintf(
char *buffer,
const char *format [,
argument] ...
);

Return Value
The number of characters written

то есть фактически указатель на конец строки. Но как замена strcpy или strcat не пойдет — форматные операции как-никак. Я думаю, что внутри она при формате %s ничего с символами не делает, но все равно как замена не годится — парсинг формата не отменишь.

>>>В функциях текстовой обработки или поиска достаточно часто требуется вернуть фрагмент подстроки.


PD>>А если мне модифицировать строки надо, да еще с изменением длины, когда inplace нельзя, а фрагменты эти даром не нужны — тогда как ?


FR>Тогда конечно только вручную на ассемблере




Пора, наверное, заканчивать ?
With best regards
Pavel Dvorkin
Re[38]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 08:10
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Пора, наверное, заканчивать ?


Угу
Re[35]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 08:13
Оценка:
Здравствуйте, Klapaucius, Вы писали:

PD>>Можно насчет значения константы поинтересоваться и о том, что делать, если истинная длина строки больше ее ?


K>Значение этой константы — размер двух указателей на границы интервала (или двух индексов) или размер одного узла дерева и т.д. Зависит от структуры данных. И длинна строки, разумеется, занчительно больше.


Ты хоть сам понимаешь, что написал ? Не говоря уж о том, что первую фразу понять невозможно, как это длина строки значительно больше, если ты сам сказал, что для строк выделяется память в размере этой самой константы ???

K>Один раз (во время компиляции


Супер! Остается только все строки в исходники включить!

> или чтения из файла, например), а не много раз, как в случае, когда размер не хранится вместе со строкой.


А как ты думаешь, если длина у меня не хранится, то я могу, если надо, ее все же один раз вычислить и хранить ? Если надо. А вот ты можешь ее не вычислять и не хранить, если не надо ?

PD>>б) в ряде случаев можно потратить на вычисление длины нулевое время, потому как она совсем не нужна


K>Это существенного значения не имеет.


Для тебя.
With best regards
Pavel Dvorkin
Re[21]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 08:16
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


GN>>>Это процесс времени трансляции. Компилятор С++ помещает нужную информацию в объектник не для всех случаев. Решается линковкой оттранслированного асм файла (не содержащего кстати ни одной мнемоники)


PD>>Ничего не понял. Как это асм файл можно линковать ???


GN>Имеется ввиду объектник.


С объектником ясно, но все же не пойму, почему править PE заголовок можно только на асме, а на С нельзя. Что там такое в асме есть особенное ?

PD>>Кстати, насчет твоей GetSeperMegaFastThreadID. Проверял, быстрее. А вот счет 1:0 не признаю. Ты же алгоритм изменил. Твой быстрее, верно, но при чем тут ассемблер ?


GN>Вот я к тому и веду — что от ассемблера мало что зависит


От алгоритма больше, согласен
With best regards
Pavel Dvorkin
Re[17]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 08:25
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Двумя словами — проход с барьером. Если хочешь пример аналога без битов — проход циклического списка с псевдоначалом (неким выбранным элементом, с которого стартуем и который содержит, скажем, NULL в поле данных).


GN>То что я называю маркером, имеет значение совпадающее с возможным для данных.


NULL — совершенно корректное значение для данных. Впрочем, если не нравится NULL — поставь указатель на некий статический объект и проверяй на равенство ему.

PD>>Другое дело, что это лишнее, проход и без этого "маркера" можно провести.


GN>Можно, но потребует дополнительных ресурсов.


Каких ?

cur = start->next; // начало с NULL пропустим
while(cur->data)
cur = cur->next;

Это с моим нулем.


и

cur = start;
do {
cur = cur->next;
}
while(cur!=start);


без него

Наоборот, одни элементом в списке меньше. Экономия

PD>>Не так уж мало. И там и тут проход с барьером. Только ты (и я в варианте со списком) этот барьер заносишь явно, а для char* его занесли до нас.


GN>Аналогом могла бы служить последовательность только из байтов 0 и 1.


Ну где я тебе возьму такие байты ? И чем тебя остальные 254 не устраивают ?
With best regards
Pavel Dvorkin
Re[39]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 08:25
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Пора, наверное, заканчивать ?


FR>Угу


With best regards
Pavel Dvorkin
Re[36]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 01.10.09 08:32
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ты хоть сам понимаешь, что написал ?


Отлично понимаю. А вы?

PD>Не говоря уж о том, что первую фразу понять невозможно, как это длина строки значительно больше, если ты сам сказал, что для строк выделяется память в размере этой самой константы ???


Я этого не говорил. Размер памяти для размещения строк линейно зависит от их длинны. О какой константе тут речь? Для результата конкатенации строк длинной N и K нужно от O(1) до O(log (min (N, K))) и для выделения подстроки от O(1) до O(log N) памяти. В зависимости от структуры данных. Понятно? Или мне теперь еще и преподавателю программирования объяснять что такое деревья?

>> или чтения из файла, например), а не много раз, как в случае, когда размер не хранится вместе со строкой.


PD>А как ты думаешь, если длина у меня не хранится, то я могу, если надо, ее все же один раз вычислить и хранить ? Если надо. А вот ты можешь ее не вычислять и не хранить, если не надо ?


Предпочтение следует отдавать статистически более вероятным вариантам использования а не статистически невероятным.

K>>Это существенного значения не имеет.

PD>Для тебя.

Ну и сколько процентов время увеличения целого счетчика на размер блока составляет от времени чтения этого блока с диска?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[37]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 08:43
Оценка: -1
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Ты хоть сам понимаешь, что написал ?


K>Отлично понимаю. А вы?


Нет. У меня телепатических способностей нет.

PD>>Не говоря уж о том, что первую фразу понять невозможно, как это длина строки значительно больше, если ты сам сказал, что для строк выделяется память в размере этой самой константы ???


K>Я этого не говорил. Размер памяти для размещения строк линейно зависит от их длинны. О какой константе тут речь?


Вот об этой

>Выделить подстроку можно, например, выделяя константное кол-во памяти, а не линейное.


http://rsdn.ru/forum/philosophy/3553842.1.aspx
Автор: Klapaucius
Дата: 01.10.09



>Для результата конкатенации строк длинной N и K нужно от O(1) до O(log (min (N, K))) и для выделения подстроки от O(1) до O(log N) памяти. В зависимости от структуры данных. Понятно? Или мне теперь еще и преподавателю программирования объяснять что такое деревья?


Спасибо, не надо. Надо просто для начала сказать, что строку предполагается хранить в виде дерева. Из

http://rsdn.ru/forum/philosophy/3553842.1.aspx
Автор: Klapaucius
Дата: 01.10.09


этого не следует, а я не телепат.

>>> или чтения из файла, например), а не много раз, как в случае, когда размер не хранится вместе со строкой.


PD>>А как ты думаешь, если длина у меня не хранится, то я могу, если надо, ее все же один раз вычислить и хранить ? Если надо. А вот ты можешь ее не вычислять и не хранить, если не надо ?


K>Предпочтение следует отдавать статистически более вероятным вариантам использования а не статистически невероятным.


Статистику в студию! Это раз. В разных задачах разные ситуации. В моей как раз наоборот было. Это два.

K>>>Это существенного значения не имеет.

PD>>Для тебя.

K>Ну и сколько процентов время увеличения целого счетчика на размер блока составляет от времени чтения этого блока с диска?


А где я говорил, что я вообще читаю эти строки с диска ?

Ладно, все, хватит.
With best regards
Pavel Dvorkin
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 08:58
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>С объектником ясно, но все же не пойму, почему править PE заголовок можно только на асме, а на С нельзя. Что там такое в асме есть особенное ?


Никто заголовки не правит, линкер добавляет информацию из объектника при сборке. Директива .SAFESEH В С такого нет. Там возможна только автоматическая регистрация __except блоков, а не произвольных функций.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[18]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 08:58
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>>Двумя словами — проход с барьером. Если хочешь пример аналога без битов — проход циклического списка с псевдоначалом (неким выбранным элементом, с которого стартуем и который содержит, скажем, NULL в поле данных).


GN>>То что я называю маркером, имеет значение совпадающее с возможным для данных.


PD>NULL — совершенно корректное значение для данных.


Внутри С-строки?

PD> Впрочем, если не нравится NULL — поставь указатель на некий статический объект и проверяй на равенство ему.


Еще раз. В моем примере идёт последовательность битов. 1 и 0 — это валидные значения для данных. "Маркер" имеет значение 1. Помимо других проблем, нужно как-то уметь определить, что конкретный 1 — это именно маркер окончания, а не данные.

PD>>>Другое дело, что это лишнее, проход и без этого "маркера" можно провести.


GN>>Можно, но потребует дополнительных ресурсов.


PD>Каких ?


В 1м примере был использован счётчик битов.
    mov eax, [pixels]  
    mov ecx, 32  
@@: shr eax, 1  ; копируем очередной бит в Carry Flag
    ;
    ; тут что-то делаем с битом
    ;
    dec ecx  ; итерируем цикл
    jnz @b


PD>cur = start->next; // начало с NULL пропустим

PD>while(cur->data)
PD> cur = cur->next;

Одно из полей — лишнее. Осталось объедлинить data и next в одну ячейку памяти.

PD>>>Не так уж мало. И там и тут проход с барьером. Только ты (и я в варианте со списком) этот барьер заносишь явно, а для char* его занесли до нас.


GN>>Аналогом могла бы служить последовательность только из байтов 0 и 1.


PD>Ну где я тебе возьму такие байты ?


char s[] = '\0\1\1\0\1\0\1\0\1\0";

Очевидно strlen не посчитает длину.

PD> И чем тебя остальные 254 не устраивают ?


Они впринципе устраивают. Не устраивает невозможность наличия 0 в середине.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[9]: Зачем нужны циклы если есть рекурсивные функции
От: LaptevVV Россия  
Дата: 01.10.09 09:03
Оценка:
Здравствуйте, gear nuke, Вы писали:

LVV>>Я тоже. Но EDX не изменяется автоматически при выполнении команды CALL, a ESP — изменяется.


GN>Intel Architecture Software Developer's Manual, Volume 1: Basic Architecture

GN>

...

GN>Используется оно когда захочет автор.
GN>

It is possible, in some cases, to temporarily reuse ESP as a general purpose register. Since the x86 architecture is so register-starved, adding an eighth register can eliminate the need to spill variables to memory and boost the speed of a critical inner loop. I've used this in a couple of places in VirtualDub when I really needed it, and some have asked if it is actually safe to do this. The answer is yes...

здесь

Это говорит о том, что В НЕКОТОРЫХ случаях мы можем использовать ESP как регистр общего назначения. Кто ж с этим спорит. А вот ОБРАТНОЕ — НЕВЕРНО. Мы НЕ МОЖЕМ использовать ни один регистр общего назначения в качестве ESP. Оговорюсь, можно попробовать ESI и EDI, поскольку они автоматом изменяются при некоторых операциях. Но засылку в стек адреса возврата придется моделировать.
GN>"Стек значений" от eax до нуля:
GN>
GN>f:  dec eax
GN>    jz @f
GN>    call f
GN>@@: retn
GN>

Ваш фрагмент только подтверждает особый статус ESP: он тут нигде не упомянут, а используется. Попробуйте в этой роли использовать EAX — не получится. И, кстати, в стеке нет никаких параметров — только адреса возврата.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[19]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 09:43
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>>>Двумя словами — проход с барьером. Если хочешь пример аналога без битов — проход циклического списка с псевдоначалом (неким выбранным элементом, с которого стартуем и который содержит, скажем, NULL в поле данных).


GN>>>То что я называю маркером, имеет значение совпадающее с возможным для данных.


PD>>NULL — совершенно корректное значение для данных.


GN>Внутри С-строки?


Поля данных списка. Я же пример привел, см выше, и так понял, что ты о нем и говоришь.

PD>> Впрочем, если не нравится NULL — поставь указатель на некий статический объект и проверяй на равенство ему.


GN>Еще раз. В моем примере идёт последовательность битов. 1 и 0 — это валидные значения для данных. "Маркер" имеет значение 1. Помимо других проблем, нужно как-то уметь определить, что конкретный 1 — это именно маркер окончания, а не данные.


Ну знаешь ли, ты многого хочешь. Твой конкретный 1, который именно маркер, а не данные, есть в действительности однобитовый регистр под названием флаг С. А без него ты не сделаешь.

PD>>>>Другое дело, что это лишнее, проход и без этого "маркера" можно провести.


GN>>>Можно, но потребует дополнительных ресурсов.


PD>>Каких ?


GN>В 1м примере был использован счётчик битов.

GN>
    mov eax, [pixels]  
GN>    mov ecx, 32  
GN>@@: shr eax, 1  ; копируем очередной бит в Carry Flag
GN>    ;
GN>    ; тут что-то делаем с битом
GN>    ;
GN>    dec ecx  ; итерируем цикл
GN>    jnz @b
GN>


А во втором примере использован дополнительный бит (флаг С). Ты доказал, что здесь не обязательно иметь дополнительно 32 бита, а хватит одного.

PD>>cur = start->next; // начало с NULL пропустим

PD>>while(cur->data)
PD>> cur = cur->next;

GN>Одно из полей — лишнее. Осталось объедлинить data и next в одну ячейку памяти.


А чего тут объединять ? Они и так рядом в памяти лежат

PD>>>>Не так уж мало. И там и тут проход с барьером. Только ты (и я в варианте со списком) этот барьер заносишь явно, а для char* его занесли до нас.


GN>>>Аналогом могла бы служить последовательность только из байтов 0 и 1.


PD>>Ну где я тебе возьму такие байты ?


GN>
char s[] = '\0\1\1\0\1\0\1\0\1\0";

GN>Очевидно strlen не посчитает длину.

Посчитает Ответ — 0. И правильный ответ.

Кстати, ты с milti-sz форматом знаком ?

abc'\0'def'\0'xyz'\0' и ноль в конце, то есть фактически 2 нуля в конце.

Очень симпатичный формат. Им многие пользуются, даже не зная этого

PD>> И чем тебя остальные 254 не устраивают ?


GN>Они впринципе устраивают. Не устраивает невозможность наличия 0 в середине.


Если не секрет — зачем тебе в текстовых строках нужен нуль в середине ?
With best regards
Pavel Dvorkin
Re[10]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 09:46
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Это говорит о том, что В НЕКОТОРЫХ случаях мы можем использовать ESP как регистр общего назначения. Кто ж с этим спорит. А вот ОБРАТНОЕ — НЕВЕРНО.


А я обратное и не утверждаю. Как раз говорю, что нечего загонять себя в рамки.

LVV> Мы НЕ МОЖЕМ использовать ни один регистр общего назначения в качестве ESP. Оговорюсь, можно попробовать ESI и EDI, поскольку они автоматом изменяются при некоторых операциях. Но засылку в стек адреса возврата придется моделировать.


Моделировать придётся разве что получение EIP, поскольку это не GPR и напрямую недоступен.

GN>>"Стек значений" от eax до нуля:

GN>>
GN>>f:  dec eax
GN>>    jz @f
GN>>    call f
GN>>@@: retn
GN>>

LVV>Ваш фрагмент только подтверждает особый статус ESP: он тут нигде не упомянут, а используется.

Он упомянут в инструкциях call и retn. Позвольте мне воздержаться от дальнейшего цитирования мануала.

LVV> Попробуйте в этой роли использовать EAX — не получится.


Попробую ECX, что бы не менять способ передачи параметра.
    mov ecx, esp
    dec ch
    ;
f:  dec eax
    jz @f
    sub ecx, 4
    mov [ecx], @f
    jmp f
@@: add ecx, 4
    jmp [ecx-4]


LVV>И, кстати, в стеке нет никаких параметров — только адреса возврата.


Разумеется.

Только при этом придется моделировать стек в виде сохранения предыдущих значений переменных

.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[38]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 01.10.09 09:50
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>У меня телепатических способностей нет.


Для того, чтобы понять из слов "одного узла дерева" что речь идет о деревьях не нужно быть телепатом, так что второй раз переспрашивать нужно разве только для того, чтобы увести разговор от темы.
Для того, чтобы понять, что речь с самого начала шла о деревьях также не нужно телепатии — нужны минимальные представления о структурах данных.

Разговоры о телепатии для меня интереса не представляют — мы говорим об эффективной реализации строк и я привел примеры структур данных, для которых типичные операции со строками алгоритмически более выгодны. Какой-нибудь ответ на это будет?

PD>Статистику в студию!


Интересует статистика — ее не сложно получить. Посчитать лоличество измерений длинны строки в достаточно объемном коде, который работает с ASCIIZ строками. Но уже второе ваше заявление

PD> В моей как раз наоборот было.


Указывает на то, что один случай для вас интереснее любой статистики.

PD>А где я говорил, что я вообще читаю эти строки с диска?


Ну ладно — времени получения блока по сети. Все, больше строкам взяться неоткуда. Но чтение блока откуда угодно существенно медленнее, чем инкремент счетчика блоков.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[23]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 09:52
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>С объектником ясно, но все же не пойму, почему править PE заголовок можно только на асме, а на С нельзя. Что там такое в асме есть особенное ?


GN>Никто заголовки не правит, линкер добавляет информацию из объектника при сборке. Директива .SAFESEH В С такого нет. Там возможна только автоматическая регистрация __except блоков, а не произвольных функций.


Понятно. Но это не возможности С или асма, а скорее организация работы с MASM или VC
With best regards
Pavel Dvorkin
Re[20]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 10:00
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>Еще раз. В моем примере идёт последовательность битов. 1 и 0 — это валидные значения для данных. "Маркер" имеет значение 1. Помимо других проблем, нужно как-то уметь определить, что конкретный 1 — это именно маркер окончания, а не данные.


PD>Ну знаешь ли, ты многого хочешь. Твой конкретный 1, который именно маркер, а не данные, есть в действительности однобитовый регистр под названием флаг С. А без него ты не сделаешь.


В действительности... (начинаю объяснять код) у меня один 33х битный регситр — аккумулятор с переносом. Необходимость 33х битов обусловлена необходимостью закодировать константу 32. Меньшую константу я сделаю и на С без флагов.

PD>А во втором примере использован дополнительный бит (флаг С). Ты доказал, что здесь не обязательно иметь дополнительно 32 бита, а хватит одного.


Я показал как закодировать константу 32 другой константой — размером регистра в битах.

PD>>>cur = start->next; // начало с NULL пропустим

PD>>>while(cur->data)
PD>>> cur = cur->next;

GN>>Одно из полей — лишнее. Осталось объедлинить data и next в одну ячейку памяти.


PD>А чего тут объединять ? Они и так рядом в памяти лежат


Лежа рядом в памяти, они занимают в 2 раза больший объём — дополнительные ресурсы, о которых я говорил.

PD>>>>>Не так уж мало. И там и тут проход с барьером. Только ты (и я в варианте со списком) этот барьер заносишь явно, а для char* его занесли до нас.


GN>>>>Аналогом могла бы служить последовательность только из байтов 0 и 1.


PD>>>Ну где я тебе возьму такие байты ?


GN>>
char s[] = '\0\1\1\0\1\0\1\0\1\0";

GN>>Очевидно strlen не посчитает длину.

PD>Посчитает Ответ — 0. И правильный ответ.


Для strlen правильный. Но остальные данные не будут обработаны при таком подходе.

PD>Кстати, ты с milti-sz форматом знаком ?


Да конечно, это уже бюлиже к теме

PD>Если не секрет — зачем тебе в текстовых строках нужен нуль в середине ?


Мне не нужен, я показываю что задача со strlen имеет мало общего.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[24]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 10:04
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Понятно. Но это не возможности С или асма, а скорее организация работы с MASM или VC


Да, я про то и говорю — практически все остальное делается в рамках С
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[39]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 10:04
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>У меня телепатических способностей нет.


K>Для того, чтобы понять из слов "одного узла дерева" что речь идет о деревьях не нужно быть телепатом, так что второй раз переспрашивать нужно разве только для того, чтобы увести разговор от темы.

K>Для того, чтобы понять, что речь с самого начала шла о деревьях также не нужно телепатии — нужны минимальные представления о структурах данных.

Цитирую первое твое сообщение


>Вопрос во-первых, в том, сколько динамической памяти выделяется. Выделить подстроку можно, например, выделяя константное кол-во памяти, а не >линейное. И результат конкатенации строк длинной N и K можно получить выделяя константное или логарифмическое кол-во памяти, а не N+K.


Если из этой фразы можно уловить. что речь идет о каких-то деревьях с самого начала — тогда точно, я понять ничего не умею.

K>Разговоры о телепатии для меня интереса не представляют — мы говорим об эффективной реализации строк и я привел примеры структур данных, для которых типичные операции со строками алгоритмически более выгодны. Какой-нибудь ответ на это будет?


Будет, если внятно изложишь то, о чем речь идет. Если уж речь идет о деревьях, будь добр объяснить структуру дерева. Двоичное ? Нет ? trie ? Что там в узле, буквы ?

PD>>Статистику в студию!


K>Интересует статистика — ее не сложно получить.


Вот когда получишь — тогда и будем разговаривать.

>Посчитать лоличество измерений длинны строки в достаточно объемном коде, который работает с ASCIIZ строками.


И что ?

>Но уже второе ваше заявление


PD>> В моей как раз наоборот было.


K>Указывает на то, что один случай для вас интереснее любой статистики.


И это тоже, потому что мне в моей программе нужно , чтобы в ней было хорошо. Но статистику давай. С приведением кода. А то одна только болтовня и ничем не доказанные утверждения.


PD>>А где я говорил, что я вообще читаю эти строки с диска?


K>Ну ладно — времени получения блока по сети. Все, больше строкам взяться неоткуда.


Да ну ? Так-таки и неоткуда ? Я уж не говорю про ввод с клавиатуры, хотя большинство строк именно такой генезис имеют. Я уж не говорю про OCR, из которого в компьютеры пришли остальные строки прежде чем их записали на диск или отправили в сеть.
Но открою тебе секрет — есть еще возможность из одних строк делать другие в самой программе
With best regards
Pavel Dvorkin
Re[25]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 10:13
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Понятно. Но это не возможности С или асма, а скорее организация работы с MASM или VC


GN>Да, я про то и говорю — практически все остальное делается в рамках С


Ну вроде все выяснили. С тобой интересно дискутировать

With best regards
Pavel Dvorkin
Re[21]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 10:23
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


GN>В действительности... (начинаю объяснять код) у меня один 33х битный регситр — аккумулятор с переносом. Необходимость 33х битов обусловлена необходимостью закодировать константу 32. Меньшую константу я сделаю и на С без флагов.


Ну да. Кстати, вполне можешь в 64-битный код это превратить. Ты просто играешь на специфике команды RCR.

GN>Я показал как закодировать константу 32 другой константой — размером регистра в битах.


Ну можно и так сказать. Но что это меняет ? То. что у тебя ее явно нет, а вместо этого ты ее неявно определяешь, используя специфику RCR ?

GN>>>Одно из полей — лишнее. Осталось объедлинить data и next в одну ячейку памяти.


PD>>А чего тут объединять ? Они и так рядом в памяти лежат


GN>Лежа рядом в памяти, они занимают в 2 раза больший объём — дополнительные ресурсы, о которых я говорил.


Я что-то не понял ? Ты что., хочешь 2 указателя в 4 байта засунуть ?

GN>>>
char s[] = '\0\1\1\0\1\0\1\0\1\0";

GN>>>Очевидно strlen не посчитает длину.

PD>>Посчитает Ответ — 0. И правильный ответ.


GN>Для strlen правильный. Но остальные данные не будут обработаны при таком подходе.


А их для нее нет. . Она так сделана. By design.

PD>>Кстати, ты с milti-sz форматом знаком ?


GN>Да конечно, это уже бюлиже к теме


PD>>Если не секрет — зачем тебе в текстовых строках нужен нуль в середине ?


GN>Мне не нужен, я показываю что задача со strlen имеет мало общего.


Ладно, давай заканчивать

With best regards
Pavel Dvorkin
Re[40]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 01.10.09 10:41
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

>>Вопрос во-первых, в том, сколько динамической памяти выделяется. Выделить подстроку можно, например, выделяя константное кол-во памяти, а не >линейное. И результат конкатенации строк длинной N и K можно получить выделяя константное или логарифмическое кол-во памяти, а не N+K.

PD>Если из этой фразы можно уловить. что речь идет о каких-то деревьях с самого начала — тогда точно, я понять ничего не умею.

Программист изучает структуры данных для того, чтобы по желаемой асимптотике подобрать соответствующую структуру данных. В данном случае деревья должны приходить на ум одними из первых.

PD>Будет, если внятно изложишь то, о чем речь идет. Если уж речь идет о деревьях, будь добр объяснить структуру дерева.


О, это, конечно, очень сильно повлияет на алгоритмическую сложность опираций со строками и выделяемую память. Тут важнее то, сбалансированы деревья или нет. Понятно, что конкатенация без балансировки быстрее и требует создания только одного узла, но и конкатенация строк на сбалансированных деревьях все равно имеет сложность лучше линейной, такая же ситуация и с выделяемой памятью.

PD>Двоичное ? Нет ? trie ? Что там в узле, буквы ?


Речь идет о веревках. Это линейные буферы и дерево конкатенации. Или, например, о пальчиковых деревьях. Но во втором случае, понятно, оверхэд на размещение одного символа вам не понравится.

PD>И что ?


И то. Это и будет статистика. Причем вы сами можете выбрать примкер кода из области которая вам интересна.

K>>Указывает на то, что один случай для вас интереснее любой статистики.

PD>И это тоже, потому что мне в моей программе нужно , чтобы в ней было хорошо.

Какая то перевернутая логика. Обычно решают, что нужно — исходя из того, что хорошо. Ну или соглашаются на то, что остается — но что уж тут хорошего? А назначать хорошим то, что нужно — это, простите, гегельянство какое-то!

PD>Но статистику давай. С приведением кода. А то одна только болтовня и ничем не доказанные утверждения.


Про доказательство — смешно.

K>>Ну ладно — времени получения блока по сети. Все, больше строкам взяться неоткуда.

PD>Да ну ? Так-таки и неоткуда ? Я уж не говорю про ввод с клавиатуры, хотя большинство строк именно такой генезис имеют.

Замечание потрясающей ценности. Вот уж на фоне набивания текста вручную инкремент счетчика просто ошеломляюще затратен. О чем речь!

PD>Я уж не говорю про OCR, из которого в компьютеры пришли остальные строки прежде чем их записали на диск или отправили в сеть.


О да, распознавание текста существенно замедлится однократным вычислением длинны строки. Это ж даже сравнивать невозможно — какое-то распознавание — тьфу! Мелочи. А однократное вычисление длинны — это огого!

Еще раз. Чтение блока откуда угодно существенно медленнее, чем инкремент счетчика блоков.

PD>Но открою тебе секрет — есть еще возможность из одних строк делать другие в самой программе


Правда?!? Открою секрет вам — существует арифметика. Она позволяет вычислять из длин операндов длинну результата.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 11:00
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>Я показал как закодировать константу 32 другой константой — размером регистра в битах.


PD>Ну можно и так сказать. Но что это меняет ? То. что у тебя ее явно нет, а вместо этого ты ее неявно определяешь, используя специфику RCR ?


Специфика ни при чем:
void f (uint32_t bitmask)
{
  if ( bitmask & 0x80000000 ) dosmth();
  bitmask = bitmask + bitmask + 1; // добавляем маркер к последовательности
  do
  {
    if ( bitmask & 0x80000000 ) dosmth();
    bitmask = bitmask + bitmask;
  }
  while ( bitmask != (1 << 31) ) // ловим маркер. последовательность будет пуста
}
Есть последовательность битов, анонимной функции определённой после do передаётся остаток последовательности, она проверяет, что он не пустой.

GN>>>>Одно из полей — лишнее. Осталось объедлинить data и next в одну ячейку памяти.


PD>>>А чего тут объединять ? Они и так рядом в памяти лежат


GN>>Лежа рядом в памяти, они занимают в 2 раза больший объём — дополнительные ресурсы, о которых я говорил.


PD>Я что-то не понял ? Ты что., хочешь 2 указателя в 4 байта засунуть ?


Вроде того. Выше, в одном бите располагаются либо данные, либо маркер. С указателями впрочем очень просто. Next не нужен, если распологать последовательно, конец можно закодировать в нижних битах поинтера (портабельно, поскольку он указывает на выровненные данные) — это не такая интересная задача, решения встречаются часто.

PD>Ладно, давай заканчивать


PD>


.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[41]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 06:35
Оценка:
Здравствуйте, Klapaucius, Вы писали:

Здравствуйте, Klapaucius, Вы писали:

Ладно. Давай закончим пустые рассуждения. Вот тебе конкретная задача. Я ее не выдумал, это (с небольшими модификациями) то, что мне реально пришлось делать.

Дан файл в формате CSV. 10 полей на строчку, есть пустые поля. Поля не длинные, обычно 5-10 символов. Количество строк известно, порядка 5 миллионов. Размер файла 200 Мб, известен точно.

Делай что хочешь, но должен обеспечить

1. Выдачу этих строк в исходном порядке
2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1)
3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1)
4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")

Для п.2-4 сортировка в момент запроса не допускается. Данные должны быть готовы для выдачи в этот момент без какой бы то ни было модификации.

Вся информация должна быть в ОП, чтение из файла можно провести только один раз.
Можешь завести нужные вспомогательные структуры, массивы и т.п, но копировать строки не разрешается. Иными словами, каждая исходное текстовое поле должно присутствовать в памяти ТОЛЬКО ОДИН РАЗ. Хоть явно, хоть неявно. На вспомогательные структуры, так и быть, еще 50-70 Мб дам.

Писать программу не прошу, само собой, но расскажи, как будешь хранить данные.

Задачка несложная, не сомневаюсь, что ты решение предложишь. Просто сравним потом с моим.
With best regards
Pavel Dvorkin
Re[42]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 02.10.09 08:01
Оценка: 1 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

Это задача построения базы данных только для чтения. К строкам имеет весьма опосредованное отношение.
Мы читаем байты из потока, разбивая на блоки по разделителям и организуем в таблицу. После этого создаем вспомогательные структуры в которых храним порядок для первых трех столбцов и структуру для ускорения фильтрации. Результат запроса у нас — набор блоков, которые мы отдаем в поток. Все. Ни одной операции со строками нет. Т.е. задача совершенно нерелевантна обсуждаемым вопросам.

Теперь моя задача.

Есть текст (не разделен на строки одинаковой длины), который можно редактировать. Т.е. вставлять, удалять, добавлать в начало, в конец символ/блок символов. Должен поддерживаться "бесконечный" (пока есть свободная память) undo/redo на каждое изменение + дерево версий. Также, желательно, иметь возможность сравнивать версии. Понятно, что для хранения версии следует занимать разумный объем, сопоставимый с объемом изменений сделанных в этой версии, а не хранить весь текст.

Я, на самом деле, не понял, зачем вы поставили свою задачу. Надеюсь, что моя поможет вам переключиться с проблем, которые не связаны с операциями над строками, на проблемы, которые с этими операциями связаны.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[43]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 08:17
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


K>Это задача построения базы данных только для чтения. К строкам имеет весьма опосредованное отношение.


Имеет, имеет. База там или не база — а вот тебе файл из строк, их надо и выдавать.


K>Мы читаем байты из потока, разбивая на блоки по разделителям и организуем в таблицу


Пожалуйста, подробнее про эти таблицы. Сколько будет в них элементов и каков их размер в байтах ?

>После этого создаем вспомогательные структуры в которых храним порядок для первых трех столбцов и структуру для ускорения фильтрации.


Тоже, пожалуйста, подробнее о том. что это за структуры и каков их размер.

>Результат запроса у нас — набор блоков, которые мы отдаем в поток.


Куда отдаем — не суть важно, а вот что это за блоки и каков их размер — пожалуйста, подробнее.

>Все. Ни одной операции со строками нет.


Изменения строк действительно нет. Это верно. Но из этого не следует, что нет работы с ними.

>Т.е. задача совершенно нерелевантна обсуждаемым вопросам.


Хоть релевантна, хоть нет, а размер вспомогательных данных оцени. И как будешь собственно символы строк — тоже. В виде строк (String C#, string STL...) или как ?


K>Теперь моя задача.


Жду сначала ответы для моей задачи.


K>Я, на самом деле, не понял, зачем вы поставили свою задачу. Надеюсь, что моя поможет вам переключиться с проблем, которые не связаны с операциями над строками, на проблемы, которые с этими операциями связаны.


Смотря что под операциями понимать
With best regards
Pavel Dvorkin
Re[44]: уточнение
От: Pavel Dvorkin Россия  
Дата: 02.10.09 08:20
Оценка:
Да, забыл сказать. Исходные строки в ASCII. Но об этом можешь не беспокоиться. Будем считать, что в твоем распоряжении класс ASCIIString, ведет себя как обычный класс String, только хранит байты, а не двухбайтники.
With best regards
Pavel Dvorkin
Re[44]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 02.10.09 10:05
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Имеет, имеет. База там или не база — а вот тебе файл из строк, их надо и выдавать.


Не имеет. По-вашему, например, решение уравнения пьезопроводности тоже работа со строками, если мы читаем входные данные из текстового файла, ага?

K>>Мы читаем байты из потока, разбивая на блоки по разделителям и организуем в таблицу

PD>Пожалуйста, подробнее про эти таблицы. Сколько будет в них элементов

Сколько значений разделенных запятыми, столько и блоков.

PD>и каков их размер в байтах ?


Не имеет никакого значения.

>>После этого создаем вспомогательные структуры в которых храним порядок для первых трех столбцов и структуру для ускорения фильтрации.

PD>Тоже, пожалуйста, подробнее о том. что это за структуры и каков их размер.

Первые гне имеют совсем уже никакого отношения к работе со строками. Ну, например, списки номеров строк таблицы сортированные по соответствующему столбцу. Во втором случае это зависит от того, что требуется от фильтрации — точное соответсвие или сопоставление с образцом.

PD>а вот что это за блоки и каков их размер — пожалуйста, подробнее.

"читаем байты из потока, разбивая на блоки по разделителям"

>>Все. Ни одной операции со строками нет.

PD>Изменения строк действительно нет. Это верно.

На этом, в общем-то можно было и закончить.
Строки можно и не изменять. Я говорю о том, что нет операций над строками. Вернее есть, конкатенация, но она выполняется выходным потоком. Т.е. можно при решении этой задачи обойтись без строк (т.е. некоторого абстрактного типа данных, для которого есть операции конкатенации, вставки, удаления, выделения подстроки и т.д.) вообще.

PD>Но из этого не следует, что нет работы с ними.


К обсуждаемой теме это отношения не имеет.

>>Т.е. задача совершенно нерелевантна обсуждаемым вопросам.

PD>Хоть релевантна, хоть нет, а размер вспомогательных данных оцени. И как будешь собственно символы строк — тоже. В виде строк (String C#, string STL...) или как ?

Не релевантна и не обсуждается.

PD>Жду сначала ответы для моей задачи.


А, ну понятно, вы сейчас будете ждать, пока я подсчитаю все биты до последнего. Так дело не пойдет. Сейчас вы решаете мою задачу с той же степенью конкретизации, что и я вашу. А там видно будет. Биты считать не надо. Нужен асимптотический анализ сложности алгоритмов и расходов памяти.

PD>Смотря что под операциями понимать


Понимать следует:
конкатенацию,
выделение подстроки,
удаление подстроки,
вставку подстроки.

Что вообще говоря было перечислено в моей задаче.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[45]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 10:32
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Не имеет. По-вашему, например, решение уравнения пьезопроводности тоже работа со строками, если мы читаем входные данные из текстового файла, ага?


Если исходные данные читаем из текстовых строк и парсим их — да. Но это к делу не относится.

K>>>Мы читаем байты из потока, разбивая на блоки по разделителям и организуем в таблицу

PD>>Пожалуйста, подробнее про эти таблицы. Сколько будет в них элементов

K>Сколько значений разделенных запятыми, столько и блоков.


Отлично.

PD>Дан файл в формате CSV. 10 полей на строчку, есть пустые поля. Поля не длинные, обычно 5-10 символов. Количество строк известно, порядка 5 миллионов. Размер файла 200 Мб, известен точно.


5 миллионов строк. 10 полей на строку. 50 миллионов полей.

PD>>и каков их размер в байтах ?


K>Не имеет никакого значения.


Имеет. Потому что я написал в условии

PD>На вспомогательные структуры, так и быть, еще 50-70 Мб дам.



При таких условиях на каждый из этих блоков получается не более чем по 1, от силы 2 байта. А на блок надо хоть ссылку, хоть указатель оформить. А ее (его) размер 4 байта. А длину блока хранить будем ? Если в формате, как в string, то это еще 4 байта, итого 8. 8 байт на 50 миллионов полей — 400 Мб.

Понял теперь, куда я веду ?


K>На этом, в общем-то можно было и закончить.


Ты сначала с размерами вспомогательных данных разберись, а потом и закончим.

PD>>Но из этого не следует, что нет работы с ними.


K>К обсуждаемой теме это отношения не имеет.


Ну-ну. Я-то ведь в свои 50-70 Мб уложусь.

K>А, ну понятно, вы сейчас будете ждать, пока я подсчитаю все биты до последнего.


Я их уже подсчитал, хоть и не до последнего. Кое-что еще добавится.

K>Ну, например, списки номеров строк таблицы сортированные по соответствующему столбцу.


Как эти списки делать будешь — не спрашиваю, а вот размер оценим.

Пусть 4 байта на элемент списка (что явно занижено, ну да ладно). Пусть только по первым 3 полям. А строк у нас 5 миллионов. Еще 20 Мб на каждую строку и каждый столбец. На 3 столбца — 60 Мб.

Итого 400 Мб + 60 Мб = 460 Мб




>Так дело не пойдет. Сейчас вы решаете мою задачу с той же степенью конкретизации, что и я вашу.


Пока что решения нет. У меня дополнительных 500 Мб не имеется. Меня за такое решение выгонят сразу.


>А там видно будет. Биты считать не надо. Нужен асимптотический анализ сложности алгоритмов и расходов памяти.


Все ясно. Вместо программы я должен заказчику представить асимптотический анализ сложности алгоритмов и расходов памяти. Это будет мое последнее представление в работе с ним


PD>>Смотря что под операциями понимать


K>Понимать следует:

K>конкатенацию,
K>выделение подстроки,
K>удаление подстроки,
K>вставку подстроки.

А парсинг уже не входит ? String.Split из класса String выкинуть ? А ведь я именно задачу на парсинг и представил.
With best regards
Pavel Dvorkin
Re[46]: о продолжении
От: Pavel Dvorkin Россия  
Дата: 02.10.09 10:35
Оценка:
FYI. У нас уже 17:30. В выходные я в Интернете не бываю. В понедельник у меня занятия с утра до вечера. Так что отвечу либо в понедельник, если урву время, либо во вторник. У тебя есть время подумать
With best regards
Pavel Dvorkin
Re[45]: Зачем нужны циклы если есть рекурсивные функции
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.10.09 11:00
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>А, ну понятно, вы сейчас будете ждать, пока я подсчитаю все биты до последнего.


Не, все намного смешнее. Он скажет, что у него нет времени на всякую ерунду. Мы это уже проходили.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[46]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 11:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Не, все намного смешнее. Он скажет, что у него нет времени на всякую ерунду.


Плохой из тебя предсказатель. Даже прошлое предсказывать не умеешь.
With best regards
Pavel Dvorkin
Re[46]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 02.10.09 11:07
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>400 Мб.

PD>Понял теперь, куда я веду ?

Упс! Я занял аж целых 10% оперативной памяти на моей рабочей машине!

PD>Пока что решения нет. У меня дополнительных 500 Мб не имеется.


К порядку! Во вводной небыло сказано, что мы считаем, будто бы сейчас 2000-й год.
Так дело не пойдет. Сейчас вы решаете мою задачу с той же степенью конкретизации, что и я вашу. А там видно будет.

PD>Все ясно. Вместо программы я должен заказчику представить асимптотический анализ сложности алгоритмов и расходов памяти.


Я не ваш заказчик. Не нужно соскальзывать с темы. Мы говорим о том, что подразумевается под словами "И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком." Я вам все пытаюсь втолковать про асимптотическую сложность — только это все пролетает у вас мимо ушей и вы продолжаете заливаться соловьем про подсчет битов. Результат такого подхода может заказчика здорово огорчить.

PD>А ведь я именно задачу на парсинг и представил.


В этой задаче не требуется парсить строки — требуется парсить поток символов.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[46]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 02.10.09 11:15
Оценка:
Здравствуйте, AndrewVK, Вы писали:

K>>А, ну понятно, вы сейчас будете ждать, пока я подсчитаю все биты до последнего.

AVK>Не, все намного смешнее. Он скажет, что у него нет времени на всякую ерунду. Мы это уже проходили.

Да я, в общем-то, прочел тут не подин подобный диспут, да и сам участвовал — т.е. в принципе понимаю, что будет дальше и с кем я имею дело. И даже читая чужие аналогичные диспуты, порой, удивляюсь — зачем же человек ведет их без всякой перспективы? Но, случается, что что-то накатывает на меня и я опять, снова ввязываюсь в спор. Рационального объяснения для моих действий — увы — нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[47]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 11:16
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>400 Мб.

PD>>Понял теперь, куда я веду ?

K>Упс! Я занял аж целых 10% оперативной памяти на моей рабочей машине!


Упс не упс, а условия надо либо соблюдать, либо не браться за задачу.

PD>>Пока что решения нет. У меня дополнительных 500 Мб не имеется.


K>К порядку! Во вводной небыло сказано, что мы считаем, будто бы сейчас 2000-й год.


Во вводной было ясно сказано

PD>На вспомогательные структуры, так и быть, еще 50-70 Мб дам.


Если не можешь этому требованию удовлетворить — не берись. А почему — это мое дело. Это не упражнение, а часть реальной задачи, и там еще много чего другого есть.

K>Так дело не пойдет. Сейчас вы решаете мою задачу с той же степенью конкретизации, что и я вашу. А там видно будет.


Пока я упорно не вижу никакого решения , удовлетворяющего моим требованиям. Свое выложу на той неделе.

PD>>Все ясно. Вместо программы я должен заказчику представить асимптотический анализ сложности алгоритмов и расходов памяти.


K>Я не ваш заказчик.


Это верно. И слава богу. Но я с самого начала сказал, что это не учебное упражнение, а часть моей реальной задачи. Я должен либо ее сделать и уложиться в требования, либо признать, что не могу сделать. И это я должен сказать заказчику. Одно из двух.


>Не нужно соскальзывать с темы. Мы говорим о том, что подразумевается под словами "И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком." Я вам все пытаюсь втолковать про асимптотическую сложность — только это все пролетает у вас мимо ушей и вы продолжаете заливаться соловьем про подсчет битов. Результат такого подхода может заказчика здорово огорчить.


Ему безразлична асимптотическая сложность. Ему работающую программу надо. За асимпотоику он мне деньги платить не будет, а за программу. что я сделал — заплатил.


K>В этой задаче не требуется парсить строки — требуется парсить поток символов.


На здоровье. Можешь парсить поток символов, если тебе больше нравится такое определение. Только решение в студию!
With best regards
Pavel Dvorkin
Re[47]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 11:20
Оценка:
Здравствуйте, Klapaucius, Вы писали:


K>Да я, в общем-то, прочел тут не подин подобный диспут, да и сам участвовал — т.е. в принципе понимаю, что будет дальше и с кем я имею дело. И даже читая чужие аналогичные диспуты, порой, удивляюсь — зачем же человек ведет их без всякой перспективы?


Да, очень красиво. Если решения дать не можешь, то надо перейти на личности. Печально.
With best regards
Pavel Dvorkin
Re[48]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 02.10.09 11:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Это не упражнение, а часть реальной задачи


Это умозрительное уражнение с высосанными из пальца граничными условиями. У моего упражнения — высосанных из пальца граничных условий нет — да еще и к предмету разговора упражнение имеет непосредственное отношение, чего о вашем не скажешь. Если мне в реальности заказчик поставит задачу написать велосипедную базу данных — я честно постараюсь его убедить что для такого объема есть базы данных и даже бесплатные — я не настолько стеснен в средствах чтобы наживаться на чужих слезах. В том случае, если он будет настаивать — я, пожалуй, отойду подальше, а то вдруг заказчик меня за ногу укусит, а мне потом уколы ставить в живот?

PD>Пока я упорно не вижу никакого решения , удовлетворяющего моим требованиям.


Ну ладно — допустим это моя проблема. Но я бы все-таки хотел задачу, которая имеет отношение к обработке строк.

PD>Свое выложу на той неделе.


Ура!

PD>Я должен либо ее сделать и уложиться в требования, либо признать, что не могу сделать. И это я должен сказать заказчику.


А почему заказчик не хотел пользоваться базой данных?

PD>Ему безразлична асимптотическая сложность. Ему работающую программу надо. За асимпотоику он мне деньги платить не будет, а за программу. что я сделал — заплатил.


Это демагогия. Если вам платят деньги за производительность — то в первую очередь это плата за асимптотическую сложность — а во вторую — за полировку битов.

PD>На здоровье. Можешь парсить поток символов, если тебе больше нравится такое определение. Только решение в студию!


Вы во второй раз уже, фактически, признали, что к теме это отношения не имеет. Зачем мне тогда ее решать? Вернее зачем я ее уже решил?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[48]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 02.10.09 11:45
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Если решения дать не можешь, то надо перейти на личности. Печально.


О чем это вы? Я тут, вообще говоря, обсуждал и осуждал только весьма несовершенную свою собственную личность.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[47]: Зачем нужны циклы если есть рекурсивные функции
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.10.09 12:05
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Плохой из тебя предсказатель. Даже прошлое предсказывать не умеешь.


Это не предсказание, это констатация факта. Я как то твою задачку уже решал, а ты в ответ увильнул под смешным предлогом.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[47]: Зачем нужны циклы если есть рекурсивные функции
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.10.09 12:05
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K> И даже читая чужие аналогичные диспуты, порой, удивляюсь — зачем же человек ведет их без всякой перспективы?


Некоторые паталогически не способны признать свою неправоту. Это очень хорошо видно, когда человек под конец начинает говорить горы абсурда, либо сваливается на грубую демагогию и хамство.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[49]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 12:12
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Это не упражнение, а часть реальной задачи


K>Это умозрительное уражнение с высосанными из пальца граничными условиями.


Мне за него деньги заплатили. Это раз. Во-вторых, если уж так — надо было сразу сказать, а не пытаться решать.


>У моего упражнения — высосанных из пальца граничных условий нет — да еще и к предмету разговора упражнение имеет непосредственное отношение, чего о вашем не скажешь. Если мне в реальности заказчик поставит задачу написать велосипедную базу данных — я честно постараюсь его убедить что для такого объема есть базы данных и даже бесплатные — я не настолько стеснен в средствах чтобы наживаться на чужих слезах.


Данные представлены из источника, который мне передать не могут. Причины обсуждать здесь не будем. Мне представлен текстовый файл в формате CSV. У меня нет оснований отказаться от его обработки.

PD>>Пока я упорно не вижу никакого решения , удовлетворяющего моим требованиям.


K>Ну ладно — допустим это моя проблема.


Это надо понимать как отказ от попыток найти решение ? Если да — выложу свое (не сегодня). Если нет — жду продолжения.


>Но я бы все-таки хотел задачу, которая имеет отношение к обработке строк.


А это и есть задача на парсинг текстового файла. А он, как всем известно, состоит из строк. Независимо от того, как они представлены — в виде char*, string всех сортов или же заканчиваются CR/LF. В CSV файле лежат текстовые строки, а это задача на их обработку.


PD>>Свое выложу на той неделе.


K>Ура!




PD>>Я должен либо ее сделать и уложиться в требования, либо признать, что не могу сделать. И это я должен сказать заказчику.


K>А почему заказчик не хотел пользоваться базой данных?


См. выше.

PD>>Ему безразлична асимптотическая сложность. Ему работающую программу надо. За асимпотоику он мне деньги платить не будет, а за программу. что я сделал — заплатил.


K>Это демагогия. Если вам платят деньги за производительность — то в первую очередь это плата за асимптотическую сложность — а во вторую — за полировку битов.


Асимптотика совершенно была неинтересна. Эти данные такие, как они есть, и в будущем объем этих данных может увеличиться не более чем на 5-10%. Поэтому мне надо было сделать именно с существующим файлом, ну и предусмотреть возможность, что он будет слегка побольше когда-нибудь. Меньше он стать не может. Больше даже в 1.5 раза он быть не сможет. По крайней мере в 21 веке .

K>Вы во второй раз уже, фактически, признали, что к теме это отношения не имеет. Зачем мне тогда ее решать? Вернее зачем я ее уже решил?


Решение, не удовлетворяющее требованиям, не есть решение. Неужели это надо объяснять ?
With best regards
Pavel Dvorkin
Re[48]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 12:15
Оценка:
Здравствуйте, AndrewVK, Вы писали:

PD>>Плохой из тебя предсказатель. Даже прошлое предсказывать не умеешь.


AVK>Это не предсказание, это констатация факта.



Твое сообщение (преддыдущее) от 18:00, а мой ответ был дан в 17:32

http://rsdn.ru/forum/philosophy/3555430.1.aspx
Автор: Pavel Dvorkin
Дата: 02.10.09


и там ни слова о скорости.
With best regards
Pavel Dvorkin
Re[49]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 02.10.09 12:19
Оценка:
Здравствуйте, Klapaucius, Вы писали:

PD>>Если решения дать не можешь, то надо перейти на личности. Печально.


K>О чем это вы? Я тут, вообще говоря, обсуждал и осуждал только весьма несовершенную свою собственную личность.


>т.е. в принципе понимаю, что будет дальше и с кем я имею дело.


Выделенное тоже относится к твоей собственной несовершенной личности или же нет ?
With best regards
Pavel Dvorkin
Re[49]: Зачем нужны циклы если есть рекурсивные функции
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.10.09 13:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>и там ни слова о скорости.


И чего?
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[42]: Зачем нужны циклы если есть рекурсивные функции
От: WolfHound  
Дата: 02.10.09 14:13
Оценка: 1 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ладно. Давай закончим пустые рассуждения. Вот тебе конкретная задача. Я ее не выдумал, это (с небольшими модификациями) то, что мне реально пришлось делать.

Как верно заметил Klapaucius эта задача абсолютно не релевантна обработке строк.
Но чтобы ты перестал гнуть пальцы веером я тебе ее решу.
Но после этого ты решишь задачу которую поставил Klapaucius.

PD>Дан файл в формате CSV. 10 полей на строчку, есть пустые поля. Поля не длинные, обычно 5-10 символов. Количество строк известно, порядка 5 миллионов. Размер файла 200 Мб, известен точно.

Если у нас есть гарантия что общая длинна строки не может быть больше 255 байт то мы делаем следующее преобразование:
Превращаем каждую строку исходного файла в структуру вида:
Первый байт суммарная длинна полей. Следующие 9 байт начала полей с второго по 10ое. Начало первого мы знаем.
Далее идут поля без разделителей.
Очевидно что мы заняли ровно столько же памяти сколько занимал исходный CSV. А если в CSV использовались двухбайтовые переводы строк то мы еще и 5 метров сэкономили. А если там были заэскейпленные поля то еще больше.
Попутно собираем массив смещений структур.
Далее делаем еще 2 копии этого массива и сортируем все 3 массива по соответствующему полю.

PD>1. Выдачу этих строк в исходном порядке

Бежим по структуре и...

PD>2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1)

Бежим по соответствующему индексу...

PD>3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1)

Бежим по соответствующему индексу, а выдачу полей по вышеописанной структуре я думаю ты сам осилишь.

PD>4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")

Двоичным поиском находим начало и конец соотвествующего интервала в нужном нам индексе. Далее см пункт 3.

PD>Можешь завести нужные вспомогательные структуры, массивы и т.п, но копировать строки не разрешается. Иными словами, каждая исходное текстовое поле должно присутствовать в памяти ТОЛЬКО ОДИН РАЗ. Хоть явно, хоть неявно. На вспомогательные структуры, так и быть, еще 50-70 Мб дам.

Итого +60М на 3 индекса -мусор из SCV.
Заметь твои любимые asciiz строки не понадобились. Более того на всех этапах у нас всегда известна длинна строки.

Твоя очередь.
Очень хочется увидеть решение на asciiz строках
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[46]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 03.10.09 14:29
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>При таких условиях на каждый из этих блоков получается не более чем по 1, от силы 2 байта. А на блок надо хоть ссылку, хоть указатель оформить. А ее (его) размер 4 байта.


Для "указателя" достаточно полбайта.

Поля не длинные, обычно 5-10 символов


PD>А длину блока хранить будем ?


Нет необходимости, можно вычислять как разницу "указателей".

PD> Если в формате, как в string, то это еще 4 байта, итого 8. 8 байт на 50 миллионов полей — 400 Мб.


25Мб вроде выходит?
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[50]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 05.10.09 04:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

PD>>и там ни слова о скорости.


AVK>И чего?


Предсказатель из тебя плохой
With best regards
Pavel Dvorkin
Re[42]: решение мойе задачи
От: Pavel Dvorkin Россия  
Дата: 05.10.09 04:49
Оценка:
PD>Дан файл в формате CSV. 10 полей на строчку, есть пустые поля. Поля не длинные, обычно 5-10 символов. Количество строк известно, порядка 5 миллионов. Размер файла 200 Мб, известен точно.

PD>Делай что хочешь, но должен обеспечить


PD>2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1)

PD>3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1)
PD>4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")

PD>Для п.2-4 сортировка в момент запроса не допускается. Данные должны быть готовы для выдачи в этот момент без какой бы то ни было модификации.


PD>Вся информация должна быть в ОП, чтение из файла можно провести только один раз.

PD>Можешь завести нужные вспомогательные структуры, массивы и т.п, но копировать строки не разрешается. Иными словами, каждая исходное текстовое поле должно присутствовать в памяти ТОЛЬКО ОДИН РАЗ. Хоть явно, хоть неявно. На вспомогательные структуры, так и быть, еще 50-70 Мб дам.

Заводим буфер длиной на 1 байт больше чем размер файла. Читаем файл в буфер целиком в двоичном виде.

Заводим три массива указателей p1,p2,p3 размером в количество строк (оно известно)

Проходим по буферу, заменяем запятые на нули. В конце строки нет запятой, но есть CR/LF. CR заменяем на 0, LF игнорируем.

(Осторожно! В самом конце файла может CR/LF не быть. Именно поэтому я задал буфер на 1 байт больше. Если это так, записываем 0 в конце)

По ходу этого прохода формируем массив p1 как массив указателей на начала строк как они были (и есть)

Копируем p1 в p2 и p3

Сортируем p1 , используя в качестве ключа первое текстовое поле. Там asciiz, так что используем стандартные qsort и strcmp

Сортируем p2 по второму, и p3 по третьему полю таким же образом. Поскольку у нас строки заканчиваются нулем, переход от одного поля к другому не вызывает проблем. Фактически мы здесь имеем почти multi-sz формат, только без завершающего нуля.

PD>1. Выдачу этих строк в исходном порядке


Пройти буфер подряд без использования этих указателей

PD>2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1)


Пройти буфер в порядке p1, p2 или p3

PD>3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1)


Аналогично 2, но выбирать только нужные поля.

PD>4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")


Провести двоичный поиск в массиве p1, p2 или p3 соответственно, найти начало и конец участка, соответствующего требуемому полю сортировки, далее аналогично 3.

Задача решается для любого размера как исходных строк, так и полей.
With best regards
Pavel Dvorkin
Re[43]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 05.10.09 04:50
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Pavel Dvorkin, Вы писали:


WH>Но после этого ты решишь задачу которую поставил Klapaucius.


Непременно. Я уж решение сделал, но выложу либо сегодня попозже, либо завтра.

PD>>Дан файл в формате CSV. 10 полей на строчку, есть пустые поля. Поля не длинные, обычно 5-10 символов. Количество строк известно, порядка 5 миллионов. Размер файла 200 Мб, известен точно.

WH>Если у нас есть гарантия что общая длинна строки не может быть больше 255 байт

Нет такой гарантии. В условиях ничего об этом не сказано.

WH>Твоя очередь.

WH>Очень хочется увидеть решение на asciiz строках

http://rsdn.ru/forum/philosophy/3557527.1.aspx
Автор: Pavel Dvorkin
Дата: 05.10.09
With best regards
Pavel Dvorkin
Re[47]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 05.10.09 04:52
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


GN>Для "указателя" достаточно полбайта.

Поля не длинные, обычно 5-10 символов


Обычно Сильно рискуешь.
With best regards
Pavel Dvorkin
Re[48]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 05.10.09 05:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>Для "указателя" достаточно полбайта.

Поля не длинные, обычно 5-10 символов


PD>Обычно Сильно рискуешь.


Применяя Хаффмана, или арифметическое кодирование?
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[43]: решение твоей задачи
От: Pavel Dvorkin Россия  
Дата: 05.10.09 05:58
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Есть текст (не разделен на строки одинаковой длины), который можно редактировать. Т.е. вставлять, удалять, добавлать в начало, в конец символ/блок символов. Должен поддерживаться "бесконечный" (пока есть свободная память) undo/redo на каждое изменение + дерево версий. Также, желательно, иметь возможность сравнивать версии. Понятно, что для хранения версии следует занимать разумный объем, сопоставимый с объемом изменений сделанных в этой версии, а не хранить весь текст.


Убедительная просьба — дочитать до конца, прежде чем комментировать.

Начнем с требования "бесконечный" (пока есть свободная память) undo/redo на каждое изменение + дерево версий.

Пройдем по виртуальному пространству (как — описано у Рихтера), найдем максимальный блок (обычно это 1.7-1.8 Гб). Захватим его с помощью VirtualAlloc. Это и будет наша свободная память. Все нижеописанные структуры будут храниться там. Назовем эту область буфером (Б).

Б будет заполняться чисто последовательно, то есть запишем туда n байт чего бы то ни было и продвинем текущий указатель на n — и т.д, пока не исчерпаем память. В дальнейшем, говоря о занесении в Б, я об этом упоминать больше не буду.

Примечание. Если ты готов придраться к тому, что при этом не будут использованы остальные маленькие блоки, то захватим все блоки и сделаем Б как список из этих блоков. Это усложнит реализацию, но на идею не повлияет.

Заведем дерево версий (ДВ). Это дерево произвольной арности. Элемент дерева содержит

указатель на родителя
список указателей на чайлдов
указатель на список фрагментов текста ( о нем ниже)
порядковый номер версии (о нем ниже).

Заведем список фрагментов (СФ). Элемент списка содержит указатель на начало фрагмента, на конец фрагмента, и указатель на следующий фрагмент.

Создадим корень ДВ и поместим его в Б. После него разместим в Б исходный текст. СФ в корневом элементе имеет один элемент , показывающий на начало и конец текста. Текущий узел — корень.

Подготовка закончена.

Начнем с удаления символов или подстроки.

Строим нового чайлда от текущего узла. Копируем его список и производим в нем изменения.

Например

Исходный текст abcdefg, исходный список — (a,g). Требуется удалить cd. Новый список (a,b)-(e,g)

Естественно, под a,b,e,g здесь понимаются указатели на соответствующие места в Б.

Замечу, что никакого удаления я реально вообще не произвожу в самом тексте.

Добавление.

Мне вообще-то все равно, в начало, в конец или куда-то еще.
Добавляемый фрагмент — в Б. Без длины и разделителей.
Строим нового чайлда от текущего узла. Копируем его список и производим в нем изменения.

Например, пусть после предыдущего удаления нужно добавить "xyz" после a. "xyz" записываем в Б.

Получим

(a,a)-(x,z)-(b,b)-(e,g).

Замечу, что никакого добавления я реально вообще не произвожу в самом тексте.

Замена. Кстати, в задаче отсутствует. Решается элементарно — удаление и последующая вставка в одной операции.

Можно после получения нового списка попробовать "сжать" его. Пусть у нас образовался в нем кусок из 5 элементов, а каждый элемент показывает на однобуквенный фрагмент. Ясно, что 5 элементов списка занимают больше места, чем один элемент списка + 5. Объединим эти 5 букв в новый фрагмент и добавим его в Б. 5 элементов ликвидируем, заведем один и пусть он показывает на этот новый фрагмент

Все новые фрагменты текста, узлы ДВ, СФ хранятся в Б. До его исчерпания.

Undo — перейти к родителю в ДВ
Redo — перейти к младшему чайлду в ДВ.
Сравнение версий — получить указатели на два узла ДВ и сравнить тексты.

//////////////////////////////////////////////////////////////////////////////

На этом можно бы и закончить. Но вот такое вот место в условии несколько двусмысленно и может дать повод для придирок

>Понятно, что для хранения версии следует занимать разумный объем, сопоставимый с объемом изменений сделанных в этой версии, а не хранить весь текст


Весь текст я не храню. Более того, по объему хранимых байтов текста тут явный минимум. Но вот насчет "объем, сопоставимый с объемом изменений сделанных в этой версии" — как сказать. Список-то я копирую каждый раз. Так что с одной стороны я вроде этому требованию удовлетворяю, а с другой — нет

(Написал это и подумал — нет, не минимум. Можно еще уменьшить. При добавлении текста ищем его среди всех текстовых фрагментов Б (как подстроку). Если найдем, то в Б его не добавляем, оформляем СФ с указателями на найденный кусок

Ликвидируем СФ. Вместо него заведем ориентированный граф фрагментов (ГФ) В начальной ситуации этот граф содержит тот же список, что и выше. Назовем этот список путем в графе (ПГ). Итак, узел ДВ имеет указатель на путь в графе (который есть СФ де-факто)

При создании чайлда список не копируем. Вместо этого анализируем ПГ родителя, определяем затронутую операцией часть ПГ. Создаем новый ПГ, который частично включает в себя куски родительского ПГ

Например

У родителя ПГ состоит из 10 фрагментов. Выясняем, что изменение касается только фрагментов 6 и 7 (замечу, что любое изменение касается только последовательных фрагментов и только один раз) и вместо них нужно добавить 1 новый фрагмент
Новый ПГ будет — 5 элементов из старого ПГ. В 5 элементе устраиваем развилку на новый элемент, а от него — на старый 8-й.

Для того, чтобы в дальнейшем найти нужный путь, помечаем все ребра в этом ПГ номером версии. В "развилке" берем то направление, которое соответствует текущей версии. Если текущей версии нет, то максимальной из версий, не большей текущей. Номер версии храним в элементе ДВ, это просто автоинкрементное значение. Впрочем, здесь надо продумать еще раз. Может, имеет смысл timestamp использовать.

Примечание 1. Если везде, где говорится об указателе, использовать смещение от начала Б, то весь Б можно выгрузить в файл, а потом загрузить заново и продолжить редактирование. Лишь бы нашелся свободный блок не меньшего чем Б размера. Естественно, замена указателя на смещение слегка замедлит работу.
Примечание 2. Для удаления всей этой конструкции необходим один вызов VirtualFree.
With best regards
Pavel Dvorkin
Re[49]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 05.10.09 05:59
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>>>Для "указателя" достаточно полбайта.

Поля не длинные, обычно 5-10 символов


PD>>Обычно Сильно рискуешь.


GN>Применяя Хаффмана, или арифметическое кодирование?


Улучшать можно до бесконечности
With best regards
Pavel Dvorkin
Re[43]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 05.10.09 06:00
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Ладно. Давай закончим пустые рассуждения. Вот тебе конкретная задача. Я ее не выдумал, это (с небольшими модификациями) то, что мне реально пришлось делать.

WH>Как верно заметил Klapaucius эта задача абсолютно не релевантна обработке строк.
WH>Но чтобы ты перестал гнуть пальцы веером я тебе ее решу.
WH>Но после этого ты решишь задачу которую поставил Klapaucius.

http://rsdn.ru/forum/philosophy/3557582.1.aspx
Автор: Pavel Dvorkin
Дата: 05.10.09
With best regards
Pavel Dvorkin
Re[44]: решение твоей задачи
От: Klapaucius  
Дата: 05.10.09 07:49
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

Эпиграфом к вашему посту должен был стать вот этот отрывок из "Понедельника":

На углу двое юношей возились с каким-то
механическим устройством. Один убежденно говорил: "Конструкторская мысль
не может стоять на месте. Это закон развития общества. Мы изобретем его.
Обязательно изобретем. Вопреки бюрократам вроде Чинушина и консерваторам
вроде Твердолобова". Другой юноша нес свое: "Я нашел, как применить
здесь нестирающиеся шины из полиструктурного волокна с вырожденными
аминными связями и неполными кислородными группами. Но я не знаю пока,
как использовать регенерирующий реактор на субтепловых нейтронах. Миша,
Мишок! Как быть с реактором?" Присмотревшись к устройству, я без труда
узнал велосипед.


Вообще говоря, вы вплотную приблизились к изобретению веревки. Остался один шаг. Не важно даже, что вы слишком много внимания уделили деталям реализации и управлению памятью (от чего я рекомендовал воздержаться), а оценку алгоритмической сложности для операций не дали (а я рекомендовал оценки привести).

PD>Список-то я копирую каждый раз. Так что с одной стороны я вроде этому требованию удовлетворяю, а с другой — нет


Верно. Поэтому от списка конкатенации нужно перейти к дереву конкатенации. И тогда нужно будет копировать не N элементов при изменении списка, а log N при изменении дерева. Это и есть последний шаг до нормального решения. Таймстампы и регенерирующие реакторы на субтепловых нейтронах тут все-таки лишние сущности.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[50]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 05.10.09 07:58
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

>>т.е. в принципе понимаю, что будет дальше и с кем я имею дело.

PD>Выделенное тоже относится к твоей собственной несовершенной личности или же нет ?

Нет, конечно. Довольно очевидно, что тут говорится о том, что вы — великий спорщик. Чем, понятное дело, можно только гордиться.

Ну, как у Кэролла:

“I don’t think they play at all fairly,” Alice began, in rather a complaining tone, “and they all quarrel so dreadfully one can’t hear oneself speak—and they don’t seem to have any rules in particular: at least, if there are, nobody attends to them—and you’ve no idea how confusing it is all the things being alive: for instance, there’s the arch I’ve got to go through next walking about at the other end of the ground—and I should have croqueted the Queen’s hedgehog just now, only it ran away when it saw mine coming!”

“How do you like the Queen?” said the Cat in a low voice.

“Not at all,” said Alice: “she’s so extremely—” Just then she noticed that the Queen was close behind her, listening: so she went on “—likely to win, that it’s hardly worth while finishing the game.”

... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[50]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 05.10.09 08:24
Оценка: +3
Здравствуйте, Pavel Dvorkin, Вы писали:

K>>Это умозрительное уражнение с высосанными из пальца граничными условиями.

PD>Мне за него деньги заплатили. Это раз. Во-вторых, если уж так — надо было сразу сказать, а не пытаться решать.

Мне кажется очень неправдоподобным, что задача ставилась заказчиком именно в такой форме.
Т.е. вот это:

Дан файл в формате CSV. 10 полей на строчку, есть пустые поля. Поля не длинные, обычно 5-10 символов. Количество строк известно, порядка 5 миллионов. Размер файла 200 Мб, известен точно.
1. Выдачу этих строк в исходном порядке
2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1)
3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1)
4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")

похоже на задание, но вот это:

Для п.2-4 сортировка в момент запроса не допускается. Данные должны быть готовы для выдачи в этот момент без какой бы то ни было модификации.
Вся информация должна быть в ОП, чтение из файла можно провести только один раз.
Можешь завести нужные вспомогательные структуры, массивы и т.п, но копировать строки не разрешается. Иными словами, каждая исходное текстовое поле должно присутствовать в памяти ТОЛЬКО ОДИН РАЗ. Хоть явно, хоть неявно. На вспомогательные структуры, так и быть, еще 50-70 Мб дам.

совсем нет. Я понимаю, если заказчик требует определенной производительности для определенных системных требований, но какое ему дело до того, как это реализовано?

PD>А это и есть задача на парсинг текстового файла. А он, как всем известно, состоит из строк. Независимо от того, как они представлены — в виде char*, string всех сортов или же заканчиваются CR/LF. В CSV файле лежат текстовые строки, а это задача на их обработку.


Парсинг CSV — задача имеющая тривиальное решение. Вся работа в вашей задаче связана с разработкой структуры размещения читаемого файла в памяти. Которая после создания не изменяется.

K>>А почему заказчик не хотел пользоваться базой данных?

PD>Данные представлены из источника, который мне передать не могут. Причины обсуждать здесь не будем. Мне представлен текстовый файл в формате CSV. У меня нет оснований отказаться от его обработки.

Все равно непонятно. Почему нельзя загрузить CSV в базу данных, а там уже пусть БД решает что хранить на диске, что в памяти и как оптимизировать запросы?

PD>Асимптотика совершенно была неинтересна. Эти данные такие, как они есть, и в будущем объем этих данных может увеличиться не более чем на 5-10%.


Да какая разница увеличится он или нет? Из каких соображений вы выбираете алгоритмы и структуры данных? Возвращаясь к началу разговора — почему оптимизированная сортировка пузырьком может быть хуже неоптимизированной быстрой сортировки?

PD>Решение, не удовлетворяющее требованиям, не есть решение. Неужели это надо объяснять?


В требованиях были ограничения только на вспомогательные структуры данных — т.е. я так понял, на интдексы для сортировки и, возможно, фильтрации. Индексы для сортировки очевидно умещаются в 50-70мб. Вообще же речь идет только об организации размещения блоков с минимальными расходами. Какое отношение это имеет к теме беседы?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[45]: решение твоей задачи
От: Pavel Dvorkin Россия  
Дата: 05.10.09 08:25
Оценка:
Здравствуйте, Klapaucius, Вы писали:

PD>>Список-то я копирую каждый раз. Так что с одной стороны я вроде этому требованию удовлетворяю, а с другой — нет


K>Верно. Поэтому от списка конкатенации нужно перейти к дереву конкатенации. И тогда нужно будет копировать не N элементов при изменении списка, а log N при изменении дерева. Это и есть последний шаг до нормального решения. Таймстампы и регенерирующие реакторы на субтепловых нейтронах тут все-таки лишние сущности.


Я же просил дочитать до конца. Там как раз список удаляется, а вместо него граф.

А с веревками я действительно не знаком
With best regards
Pavel Dvorkin
Re[44]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 05.10.09 08:34
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

WH>>Если у нас есть гарантия что общая длинна строки не может быть больше 255 байт

PD>Нет такой гарантии. В условиях ничего об этом не сказано.

Ну, тогда максимальная длина блока, на которые строка разделяется. Сложение никто не отменял. Да и под сохранение числа можно выделять именно столько байт, сколько нужно для каждого конкретного случая. Очевидно, что если средняя длина блока 5-10, то больше половины байта редко когда понадобится.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[46]: решение твоей задачи
От: Klapaucius  
Дата: 05.10.09 08:43
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Я же просил дочитать до конца. Там как раз список удаляется, а вместо него граф.


Ну, переходить от списка к графу — это явный перелет. Ну, понятно, что теоретически через некоторое число изменений текст может вернуться к исходному виду, но создавать из-за этой эфемерной возможности себе трудности я считаю неправильным.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[47]: решение твоей задачи
От: Pavel Dvorkin Россия  
Дата: 05.10.09 12:16
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Я же просил дочитать до конца. Там как раз список удаляется, а вместо него граф.


K>Ну, переходить от списка к графу — это явный перелет. Ну, понятно, что теоретически через некоторое число изменений текст может вернуться к исходному виду, но создавать из-за этой эфемерной возможности себе трудности я считаю неправильным.


Гм...

Давай так — изложи с подробностями свои веревки. Ничего не надо, только путь в дереве. Вот предположим он состоит из 20 фрагментов. Изменения касаются фрагментов с 5 по 7, остальные (1-4 и 8-20) без изменений. Что будет представлять собой новый путь ?
With best regards
Pavel Dvorkin
Re[45]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 05.10.09 12:21
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


WH>>>Если у нас есть гарантия что общая длинна строки не может быть больше 255 байт

PD>>Нет такой гарантии. В условиях ничего об этом не сказано.

K>Ну, тогда максимальная длина блока, на которые строка разделяется. Сложение никто не отменял. Да и под сохранение числа можно выделять именно столько байт, сколько нужно для каждого конкретного случая.


А все же сколько ? Я не могу ничего гарантировать. В лучшем случае я могу еще предположить, что отдельное поле будет длиной не более 255. Но и на это я не хотел бы закладываться. Крайне маловероятно, а вдруг ? Если бы это было не в "сердце" алгоритма , то еще ладно, а ведь тут вся структура данных накроется медным тазом.

>Очевидно, что если средняя длина блока 5-10, то больше половины байта редко когда понадобится.


То, что редко — верно. А вот что делать будешь, если все же окажется 16 или больше ? Ну не могу я дать точного максимума, не знаю я его. И если даже знаю — нет гарантии, что для следующей версии там данные не изменятся.
With best regards
Pavel Dvorkin
Re[51]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 05.10.09 12:33
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, Pavel Dvorkin, Вы писали:


K>>>Это умозрительное уражнение с высосанными из пальца граничными условиями.

PD>>Мне за него деньги заплатили. Это раз. Во-вторых, если уж так — надо было сразу сказать, а не пытаться решать.

K>Мне кажется очень неправдоподобным, что задача ставилась заказчиком именно в такой форме.


Ты отчасти прав. Читай внимательно

PD>Я ее не выдумал, это (с небольшими модификациями) то, что мне реально пришлось делать.


То есть я тебе дал не реальную задачу, а некоторую модификацию. Чтобы тебе скучно не было.

K>похоже на задание, но вот это:

K>

K>Для п.2-4 сортировка в момент запроса не допускается. Данные должны быть готовы для выдачи в этот момент без какой бы то ни было модификации.
K>Вся информация должна быть в ОП, чтение из файла можно провести только один раз.
K>Можешь завести нужные вспомогательные структуры, массивы и т.п, но копировать строки не разрешается. Иными словами, каждая исходное текстовое поле должно присутствовать в памяти ТОЛЬКО ОДИН РАЗ. Хоть явно, хоть неявно. На вспомогательные структуры, так и быть, еще 50-70 Мб дам.

K>совсем нет. Я понимаю, если заказчик требует определенной производительности для определенных системных требований, но какое ему дело до того, как это реализовано?

А где я сказал про производительность ? Там ни слова о ней. И этот кусок задания — из того, что отмечено выше жирным. Чтобы тебе скучно не было

А если серьезнее — безусловными были требования по памяти. По скорости не очень. Но все же если я на каждый запрос начну сортировать — то и по скорости никуда не пойдет. Открою небольшой секрет — эти запросы SELECT вовсе не делаются. Просто надо потом эти данные переформировать (а на это место нужно!!!) в совсем иную структуру , и при этом они должны быть упорядочены по ключам, иначе я эту структуру до второго пришествия строить буду.

K>Парсинг CSV — задача имеющая тривиальное решение. Вся работа в вашей задаче связана с разработкой структуры размещения читаемого файла в памяти. Которая после создания не изменяется.


Вполне согласен. Но asciiz меня здесь спасли. В сущности, твое решение ничем от моего не отличается. Поэтому я специально в пятницу не торопился выкладывать свое, ждал, что ты сделаешь один шаг, дойдешь до ASCIIZ, и мне останется только поздравить тебя с решением . Но тебе признать формат ASCIIZ религия не позволяет

K>Все равно непонятно. Почему нельзя загрузить CSV в базу данных, а там уже пусть БД решает что хранить на диске, что в памяти и как оптимизировать запросы?


Нельзя. Давай не будем это обсуждать. Есть причины, которые я не могу раскрывать.

PD>>Асимптотика совершенно была неинтересна. Эти данные такие, как они есть, и в будущем объем этих данных может увеличиться не более чем на 5-10%.


K>Да какая разница увеличится он или нет? Из каких соображений вы выбираете алгоритмы и структуры данных?


Исключительно из требований конкретной задачи. Я пойду на нарушение любых канонов, если в данной задачае это будет оправданно.


>Возвращаясь к началу разговора — почему оптимизированная сортировка пузырьком может быть хуже неоптимизированной быстрой сортировки?


Странный вопрос. Тебе объяснить про N^2 и NlnN ?



K>В требованиях были ограничения только на вспомогательные структуры данных — т.е. я так понял, на интдексы для сортировки и, возможно, фильтрации. Индексы для сортировки очевидно умещаются в 50-70мб. Вообще же речь идет только об организации размещения блоков с минимальными расходами. Какое отношение это имеет к теме беседы?


ASCIIZ
With best regards
Pavel Dvorkin
Re[45]: и еще про твою задачу
От: Pavel Dvorkin Россия  
Дата: 05.10.09 12:46
Оценка:
Здравствуйте, Klapaucius, Вы писали:

Извини, не могу удержаться. Не хочешь — не отвечай.

Модификация твоей задачи.

Необходимо иметь возможность в любой момент выгрузить всю эту SVN целиком в файл и загрузить из файла обратно. Предполагаем, что при загрузке свободная память нужного размера найдется.

А теперь мое требование.

При записи и чтении не разрешается использовать вообще никакие сложные структуры данных. Ни явно, ни неявно. Максимум , что ты можешь себе позволить — несколько простых переменных (int, long, указатели на структуры, ссылки на экземпляры классов, но без new). Никаких новых экземпляров классов. Никаких массивов.

Сериализация дотнета ни в каком виде не проходит. Для нее внутренние буфера понадобятся.

Если ты считаешь, что задача искусственно поставлена, то.. OK. Сама задача выгрузки и загрузки в файл вполне разумна, спорить не будешь. А по твоим условиям можно использовать всю свободную память под это хозяйство. Ну вот и использовали. Нет больше памяти. Осталось кое-что в стеке, вот и работай

Я свое решение привел. Напоминаю — вместо указателей — смещения, а запись в файл — WriteFile всего этого Б. Чтение — ReadFile. Ну и CreateFile, CloseHandle, конечно.
With best regards
Pavel Dvorkin
Re[48]: offtop
От: Pavel Dvorkin Россия  
Дата: 05.10.09 13:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Некоторые паталогически не способны признать свою неправоту. Это очень хорошо видно, когда человек под конец начинает говорить горы абсурда, либо сваливается на грубую демагогию и хамство.


Когда человек сваливается на хамство — на это модератор есть. Он должен и может меры принять. Ясно и понятно сказать, что вот это является хамством, и предупредить или забанить.

Невзирая на лица.

В том числе и на лица членов RSDN-team.

И даже на свое собственное лицо. Если он того заслуживает
With best regards
Pavel Dvorkin
Re[40]: Зачем нужны циклы если есть рекурсивные функции
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.10.09 13:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Да ну ? Так-таки и неоткуда ? Я уж не говорю про ввод с клавиатуры, хотя большинство строк именно такой генезис имеют.

Как мы уже выяснили пару лет назад, "ввод с клавиатуры" в наше время означает получение строки из контрола типа EDIT. В котором, естественно, как мы тоже выяснили пару лет назад, строки в момент получения уже оборудованы длиной. Печально, что преподаватель Win32 API демонстрирует столь упорное невежество в элементарных вещах.
PD>Я уж не говорю про OCR, из которого в компьютеры пришли остальные строки прежде чем их записали на диск или отправили в сеть.
PD>Но открою тебе секрет — есть еще возможность из одних строк делать другие в самой программе
А можно в студию пример такой операции в "самой программе", при которой из "одних строк", все из которых оборудованы длиной, получается строка неизвестной длины? Ну, то есть на "узнавание" длины которой нужно потратить больше, чем O(1) времени?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[52]: Зачем нужны циклы если есть рекурсивные функции
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.10.09 13:53
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Вполне согласен. Но asciiz меня здесь спасли. В сущности, твое решение ничем от моего не отличается. Поэтому я специально в пятницу не торопился выкладывать свое, ждал, что ты сделаешь один шаг, дойдешь до ASCIIZ, и мне останется только поздравить тебя с решением . Но тебе признать формат ASCIIZ религия не позволяет

Здесь спасают не ASCIIZ, а грамотная работа с данными. Поскольку они неизменны, то достаточно построить один раз индексы. Поскольку техника работы с индексами, размер которых превышает размер доступной оперативной памяти, разработана уже очень давно, никакие велосипеды тут не нужны. Можно занять хоть 900 лишних мегабайт — всё равно при выполнении типичного запроса почти всё будет уезжать прямо из кэша.

PD>Нельзя. Давай не будем это обсуждать. Есть причины, которые я не могу раскрывать.



PD>ASCIIZ
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[41]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 06.10.09 02:51
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Да ну ? Так-таки и неоткуда ? Я уж не говорю про ввод с клавиатуры, хотя большинство строк именно такой генезис имеют.

S>Как мы уже выяснили пару лет назад, "ввод с клавиатуры" в наше время означает получение строки из контрола типа EDIT.

Даже в консольных приложениях ?


PD>>Я уж не говорю про OCR, из которого в компьютеры пришли остальные строки прежде чем их записали на диск или отправили в сеть.

PD>>Но открою тебе секрет — есть еще возможность из одних строк делать другие в самой программе
S>А можно в студию пример такой операции в "самой программе", при которой из "одних строк", все из которых оборудованы длиной, получается строка неизвестной длины? Ну, то есть на "узнавание" длины которой нужно потратить больше, чем O(1) времени?

String.Split. Правда, тут не одна строка получится, а несколько, но я и не обещал одну. Я обещал из одних — другие.
With best regards
Pavel Dvorkin
Re[44]: модификация твоей задачи
От: Pavel Dvorkin Россия  
Дата: 06.10.09 03:02
Оценка:
PD>Здравствуйте, Klapaucius, Вы писали:

Предлагаю небольшую модификацию твоей задачи.

Есть текст , разделен на строки неодинаковой длины, который можно редактировать. Т.е. вставлять, удалять, добавлять в начало, в конец символ/блок символов/блок строк. Можно добавлять как между строками редактируемого текста, так и внутрь какой-то строки, и если при этом добавляется блок строк — должно поддерживаться корректное разбиение на строки. Можно удалять блок, который начинается в середине одной строки, продолжатеся на нескольких (>=0) следующих строках и заканчивается в середине следующей строки. (В общем, как в обычном текстовом редакторе — вставка в любое место любого куска, удаление любого куска, который можно выделить Shift- стрелка и т.п.) Исходный текст изначально находится в текстовом файле.
Должен поддерживаться "бесконечный" (пока есть свободная память) undo/redo на каждое изменение + дерево версий. Также, желательно, иметь возможность сравнивать версии. Понятно, что для хранения версии следует занимать разумный объем, сопоставимый с объемом изменений сделанных в этой версии, а не хранить весь текст.

Про дерево версий и веревки писать не надо, если не будешь ничего изменять. Меня одно главным образом интересует — как будешь фрагменты текста хранить ?
With best regards
Pavel Dvorkin
Re[42]: Зачем нужны циклы если есть рекурсивные функции
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.10.09 03:11
Оценка: +1 -1
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Даже в консольных приложениях ?
В консольных приложениях строки приезжают из двух мест:
1. Командная строка — там, естественно, весь парсинг, включая выяснение длины строки, уже выполнен заранее
2. Чтение из консоли — как уже сказали, там узким местом подсчёт символов вовсе не является.

PD>String.Split. Правда, тут не одна строка получится, а несколько, но я и не обещал одну. Я обещал из одних — другие.

И? String.Split и так занимает O(N). Вычислять заодно длину получамых фрагментов — весьма несложно.
Незачёт.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[43]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 06.10.09 03:52
Оценка:
Здравствуйте, Sinclair, Вы писали:


PD>>String.Split. Правда, тут не одна строка получится, а несколько, но я и не обещал одну. Я обещал из одних — другие.

S>И? String.Split и так занимает O(N). Вычислять заодно длину получамых фрагментов — весьма несложно.
S>Незачёт.

Не пойдет. Substr тоже занимает O(M) (где M — длина вырезки), копировать-то надо. Но там длина подстроки вычисляется элементарно, а тут — нет. Ты просил пример, где нужно больше O(1), я его тебе дал. Никаких других условий не было. А если добавлять условия по ходу действия, то мы никогда не кончим.

Все, Антон, закрываю со своей стороны эту веточку. Мне дискуссии с тобой насчет строк уже изрядно надоели
With best regards
Pavel Dvorkin
Re[44]: Зачем нужны циклы если есть рекурсивные функции
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.10.09 04:19
Оценка: +1 -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Не пойдет. Substr тоже занимает O(M) (где M — длина вырезки), копировать-то надо. Но там длина подстроки вычисляется элементарно, а тут — нет.

Бр-р. Вообще-то, Split точно так же работает через Substr. И длина, естественно, вычисляется элементарно.

PD>Ты просил пример, где нужно больше O(1), я его тебе дал. Никаких других условий не было. А если добавлять условия по ходу действия, то мы никогда не кончим.

Не нужно здесь больше O(1). В тот момент, когда мы порождаем новую строку для result, мы [i]уже знаем длину — потому, что мы к этому моменту нашли сепаратор.

PD>Все, Антон, закрываю со своей стороны эту веточку. Мне дискуссии с тобой насчет строк уже изрядно надоели

Учиться, Павел, никогда не поздно. Если, конечно, не вставать в позу "вы все зашоренные, а я один знаю как правильно".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[52]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 09.10.09 16:15
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>То есть я тебе дал не реальную задачу, а некоторую модификацию. Чтобы тебе скучно не было.


Но, тем не менее, мне было скучно.

K>>Парсинг CSV — задача имеющая тривиальное решение. Вся работа в вашей задаче связана с разработкой структуры размещения читаемого файла в памяти. Которая после создания не изменяется.

PD>Вполне согласен. Но asciiz меня здесь спасли. В сущности, твое решение ничем от моего не отличается. Поэтому я специально в пятницу не торопился выкладывать свое, ждал, что ты сделаешь один шаг, дойдешь до ASCIIZ, и мне останется только поздравить тебя с решением . Но тебе признать формат ASCIIZ религия не позволяет

Отличается принципиально. Я занимаюсь парсингом CSV один раз, а вы, фактически, парсите поток байтов, разделенных, извините за каламбур, разделителями каждый раз при чтении строки таблицы, хранящейся в памяти.

PD>Нельзя. Давай не будем это обсуждать. Есть причины, которые я не могу раскрывать.


Не так страшно раскрыть причины, как отсутствие причин.

PD>Исключительно из требований конкретной задачи. Я пойду на нарушение любых канонов, если в данной задачае это будет оправданно.


Не нужно подменять понятия. "Следование канонам" и разумный выбор на основании имеющейся информации — разные вещи. И если человек не может объяснить из каких соображений он выбирает структуры данных, это может означать не столько то, что он не желает следовать каким-то там "канонам" сколько то, что он просто не понимает, что он делает.

PD>Странный вопрос. Тебе объяснить про N^2 и NlnN ?


Не страннее остального треда. Т.е. разница между N^2 и N log N вам понятна, а разница между 1 и N и между N и log N — не понятна? А если понятна, то зачем весь этот разговор?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[48]: решение твоей задачи
От: Klapaucius  
Дата: 09.10.09 16:52
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Давай так — изложи с подробностями свои веревки.


Я же уже объяснил, что вместо списка — дерево. Более подробно объяснить можно только если углублятся в детали какой-то конкретной реализации.

PD>Ничего не надо, только путь в дереве. Вот предположим он состоит из 20 фрагментов. Изменения касаются фрагментов с 5 по 7, остальные (1-4 и 8-20) без изменений. Что будет представлять собой новый путь ?


Не понял вопроса. Вы просите меня объяснить, как с помощью дерева можно организовать набор элементов, изменение которого не требует полного копирования для организации версионности? Вообще-то это надо бы знать.

Ну, вот поясняющая схема на языке dot.
N12 -> L1
N12 -> L2
N34 -> L3
N34 -> L4
N56 -> L5
N56 -> L6
N1234 -> N12
N1234 -> N34
R -> N1234
R -> N56
Rn -> N1234n
Rn -> N56
N1234n -> N12
N1234n -> N34n
N34n -> L3
N34n -> L4n
Rn [shape=box]
N1234n [shape=box]
N34n [shape=box]
L4n [shape=box]

Если у вас нет graphviz-а — просмотреть дерево можно здесь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[46]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 09.10.09 16:56
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>То, что редко — верно. А вот что делать будешь, если все же окажется 16 или больше ?


Если окажется болше, то для данного конкретного блока я использую больше памяти на хранение длины, например.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[42]: Зачем нужны циклы если есть рекурсивные функции
От: Mirrorer  
Дата: 09.10.09 23:13
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>1. Выдачу этих строк в исходном порядке

PD>2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1)
PD>3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1)
PD>4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")

PD>Для п.2-4 сортировка в момент запроса не допускается. Данные должны быть готовы для выдачи в этот момент без какой бы то ни было модификации.

поле должно присутствовать в памяти ТОЛЬКО ОДИН РАЗ. Хоть явно, хоть неявно. На вспомогательные структуры, так и быть, еще 50-70 Мб дам.

PD>Писать программу не прошу, само собой, но расскажи, как будешь хранить данные.


Считываем кортежи.
Каждому кортежу ставим в соответсвие 4 индекса интовых
0 — неотсортированный
1 — отсортированный по первому ключу
2,3, аналогично

потратили дополнительной памяти 4 * 5М = 20М

строим для них дерево по 2 указателя на каждый элемент 20 + 20 + 20 = 60

проекции строятся просто.
проверку с where делаем делением пополам.
PD>Задачка несложная, не сомневаюсь, что ты решение предложишь. Просто сравним потом с моим.

А вот мое решение. на J

load 'csv'
data =. loadcsv 'c:\temp\2.csv'
sortby =. 4 : '(/: y {"1 x) { x'

.NB пример использования
.NB неотсортированные данные
data
┌──────────┬──────────┬──────────┬──────────┐
│nraxikrsma│nzptizmpib│ysufpwcisk│uglnldenrn│
├──────────┼──────────┼──────────┼──────────┤
│yjqxwfysjs│zvlnuucnjw│nadkmzxjhp│avkwjiqsqv│
├──────────┼──────────┼──────────┼──────────┤
│rmyonuvzub│owqpsumsxb│letdgrhzfy│shcvutxgib│
├──────────┼──────────┼──────────┼──────────┤
│kvebusxbmn│awrmmxwejf│femxmsyhdr│aswmkciktq│
├──────────┼──────────┼──────────┼──────────┤
│pxbwuihpoa│dpdorgepqa│rajatewzya│aexcdzuldz│
└──────────┴──────────┴──────────┴──────────┘

.NB сортируем по первой колонке
data sortby 0
┌──────────┬──────────┬──────────┬──────────┐
│kvebusxbmn│awrmmxwejf│femxmsyhdr│aswmkciktq│
├──────────┼──────────┼──────────┼──────────┤
│nraxikrsma│nzptizmpib│ysufpwcisk│uglnldenrn│
├──────────┼──────────┼──────────┼──────────┤
│pxbwuihpoa│dpdorgepqa│rajatewzya│aexcdzuldz│
├──────────┼──────────┼──────────┼──────────┤
│rmyonuvzub│owqpsumsxb│letdgrhzfy│shcvutxgib│
├──────────┼──────────┼──────────┼──────────┤
│yjqxwfysjs│zvlnuucnjw│nadkmzxjhp│avkwjiqsqv│
└──────────┴──────────┴──────────┴──────────┘

.NB сортируем по второй колонке
 data sortby 1
┌──────────┬──────────┬──────────┬──────────┐
│kvebusxbmn│awrmmxwejf│femxmsyhdr│aswmkciktq│
├──────────┼──────────┼──────────┼──────────┤
│pxbwuihpoa│dpdorgepqa│rajatewzya│aexcdzuldz│
├──────────┼──────────┼──────────┼──────────┤
│nraxikrsma│nzptizmpib│ysufpwcisk│uglnldenrn│
├──────────┼──────────┼──────────┼──────────┤
│rmyonuvzub│owqpsumsxb│letdgrhzfy│shcvutxgib│
├──────────┼──────────┼──────────┼──────────┤
│yjqxwfysjs│zvlnuucnjw│nadkmzxjhp│avkwjiqsqv│
└──────────┴──────────┴──────────┴──────────┘

.NB сортируем по второй колонке , выбирая только первую и третью колонки
0 2 {"1 (data sortby 1)
┌──────────┬──────────┐
│kvebusxbmn│femxmsyhdr│
├──────────┼──────────┤
│pxbwuihpoa│rajatewzya│
├──────────┼──────────┤
│nraxikrsma│ysufpwcisk│
├──────────┼──────────┤
│rmyonuvzub│letdgrhzfy│
├──────────┼──────────┤
│yjqxwfysjs│nadkmzxjhp│
└──────────┴──────────┘


проверку на равенство не добавлял, но могу уверить, что это выльется еще в одну функцию которая будет фильтровать данные до сортировки.
Да, с первого раза выглядит страшно.
Да, жрет память.
Но позволяет комбинировать выборки как угодно без дополнительных телодвижений.
Позволяет транспонировать, отражать и вообще что угодно делать с матрицами не затрачивая никаких усилий.
Сортировка работает одинаково для строк и не для строк.
Для строк можно указать (легко) порядок сортировки. Хошь AaBbCc..., хошь ABCabc, или любые другие варианты.
А еще ходят слухи, что оно умеет раскидывать задачи на несколько ядер. Но тут не проверял, врать не буду.
Потрачено на реализацию полчаса, из которых 25 минут искал документацию к функциям, потому что давно не пользовался джеем. При регулярном использовании вообще плевая задача.

Есть еще альтернаривные варианты. Залить данные в БД, благо многие умеют считывать csv файлики, и получить хоть черта в ступе.

А можно csv открыть в Экселе. Кардинально да, но если задача одноразовая, пуркуа бы и не па ?

Я вообще к чему. Алгоритмы это хорошо. Это полезно, их должны знать. Но для развития имхо необходимо знать как можно больше различных подходов. чтобы решать задачу наиболее оптимальным для каждого случая способом.
Premature optimization is the root of all evil. (c)
Re[53]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 12.10.09 04:31
Оценка:
Здравствуйте, Klapaucius, Вы писали:

PD>>Вполне согласен. Но asciiz меня здесь спасли. В сущности, твое решение ничем от моего не отличается. Поэтому я специально в пятницу не торопился выкладывать свое, ждал, что ты сделаешь один шаг, дойдешь до ASCIIZ, и мне останется только поздравить тебя с решением . Но тебе признать формат ASCIIZ религия не позволяет


K>Отличается принципиально. Я занимаюсь парсингом CSV один раз, а вы, фактически, парсите поток байтов, разделенных, извините за каламбур, разделителями каждый раз при чтении строки таблицы, хранящейся в памяти.


Да, но я решил задачу, а ты нет — твое решение не удовлетворяет условиям.

With best regards
Pavel Dvorkin
Re[49]: решение твоей задачи
От: Pavel Dvorkin Россия  
Дата: 12.10.09 04:36
Оценка:
Здравствуйте, Klapaucius, Вы писали:

PD>>Ничего не надо, только путь в дереве. Вот предположим он состоит из 20 фрагментов. Изменения касаются фрагментов с 5 по 7, остальные (1-4 и 8-20) без изменений. Что будет представлять собой новый путь ?


K>Не понял вопроса. Вы просите меня объяснить, как с помощью дерева можно организовать набор элементов, изменение которого не требует полного копирования для организации версионности? Вообще-то это надо бы знать.


Слушай, может хватит меня поучать! Я тебе вполне конкретный вопрос задал. Если неясно — OK, изложу еще раз, немного упрощу

После некоторых действий для текста имеем 2 фрагмента

Фрагмент 1 показывает на кусок abcdefgh
Фрагмент 2 показывает на кусок stuvxyz

Добавляем новый фрагмент "123" между у u и v

Приведи , какие фрагменты получатся и как они выглядят.

K>Ну, вот поясняющая схема на языке dot.


Извини, но сначала следовало бы спросить, знаю ли я dot. Я его не знаю, так что это не ответ.
With best regards
Pavel Dvorkin
Re[43]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 12.10.09 04:40
Оценка:
Здравствуйте, Mirrorer, Вы писали:

M>Считываем кортежи.

M>Каждому кортежу ставим в соответсвие 4 индекса интовых
M>0 — неотсортированный
M>1 — отсортированный по первому ключу
M>2,3, аналогично

M>потратили дополнительной памяти 4 * 5М = 20М


Я что-то не понял. Строк примерно 5 миллионов. Для каждой строки (кортежа) 4 интовых индекса

5млн * 4 индекса * 4 байта_на_int = 80 Мб.

M>строим для них дерево по 2 указателя на каждый элемент 20 + 20 + 20 = 60


Ты уже и без дерева превысил ограничения.
With best regards
Pavel Dvorkin
Re[49]: решение твоей задачи
От: Pavel Dvorkin Россия  
Дата: 12.10.09 04:54
Оценка:
Здравствуйте, Klapaucius, Вы писали:

Кстати. Ты писал, что твои веревки дают копирование log(N) элементов. А в моем решении (с графом) копируется не более 2 элементов. Хоть при вставке, хоть при удалении. Да и зачем больше — путь в графе есть фактически список, а чтобы из этого списка получить новый список (новый путь в графе) путем однократного изменения , больше чем 2 элемента старого пути копировать незачем. Один слева, другой справа. Ну и еще новый элемент создать , если добавляем. Так что решение O(1).
With best regards
Pavel Dvorkin
Re[44]: Зачем нужны циклы если есть рекурсивные функции
От: Mirrorer  
Дата: 12.10.09 06:19
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


PD>Я что-то не понял. Строк примерно 5 миллионов. Для каждой строки (кортежа) 4 интовых индекса


PD>5млн * 4 индекса * 4 байта_на_int = 80 Мб.


индекс имеется ввиду позиция элемента при сортировке по i-тому столбцу, а не индекс в смысле БД
пример
i i1 i2 i3 c1 c2 c3
0  1  2  1  b  c  b  
1  2  0  3  c  a  d
2  3  3  0  d  d  a
3  0  1  2  a  b  c

где i — положение кортежей в неотсортированном виде,
i1,i2,i3 — положение кортежей в выборке, отсортированной по соотвествуем столбцу
c1,c2,c3 — данные соответственно

то есть, при сортировке строк по c1 мы должны быстро вывести строки в сдедующем порядке
сначала ту строку, где i1 ==0, потом ту, где i1 == 2, i1==3, i1 ==4

Но без дерева сложность такого бегания будет n^2

поэтому мы строим деревья для i1,i2,i3

Деревья нам позволят быстро вывести результат отсортированный по колонке, а также обеспечить двоичный поииск для сортировки с сравнением

Вроде в память в кладываемся.
Re[45]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 12.10.09 06:34
Оценка:
Здравствуйте, Mirrorer, Вы писали:

M>Здравствуйте, Pavel Dvorkin, Вы писали:



PD>>Я что-то не понял. Строк примерно 5 миллионов. Для каждой строки (кортежа) 4 интовых индекса


PD>>5млн * 4 индекса * 4 байта_на_int = 80 Мб.


M>индекс имеется ввиду позиция элемента при сортировке по i-тому столбцу, а не индекс в смысле БД


Да хоть в каком смысле, но sizeof его дай. Если его тип int — 4 байта вынь да положь. Если не int — тогда что ?

M>пример


<skipped>

Сначала с размером индекса давай разберемся.
With best regards
Pavel Dvorkin
Re[46]: Зачем нужны циклы если есть рекурсивные функции
От: Mirrorer  
Дата: 12.10.09 09:04
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Да хоть в каком смысле, но sizeof его дай. Если его тип int — 4 байта вынь да положь. Если не int — тогда что ?


Да, mea culpa. Надо подумать лучше.
Re[45]: модификация твоей задачи
От: Pavel Dvorkin Россия  
Дата: 13.10.09 04:28
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

Так что, ответа не будет ?

Приведу свое решение. Собственно, и приводить тут нечего.

Вот решение твоей исходной задачи

http://rsdn.ru/forum/philosophy/3557582.1.aspx
Автор: Pavel Dvorkin
Дата: 05.10.09


А в модифицированной мной задаче в этом решении практически ничего не надо менять. Оно работает и для текста, не поделенного на строки, и для текста из строк. Единственное, что надо изменить —

Вместо

Добавляемый фрагмент — в Б. Без длины и разделителей.

читать

Добавляемый фрагмент — в Б. Как он есть, включая имеющиеся в нем нулевые символы в конце строк. Без длины.

Вот и все. Разбиение на строки будет автоматически поддерживаться корректным образом при любой вставке или удалении.

ASCIIZ велик и могуч!
With best regards
Pavel Dvorkin
Re[3]: Зачем нужны поля в .Net?
От: komaz Россия  
Дата: 21.10.09 05:53
Оценка: 10 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, VladD2, Вы писали:


VD>>Я как-то уже думал на эту тему и пришел к выводу, что в языке можно было бы избавиться от лишней абстракции. Поля можно было бы переставлять как свойства с двумя публичными эксесорами. Это упростило бы язык и сделало бы более легким использование рефлексии (поля попросту можно было бы игнорировать во многих случаях).


PD>Я бы проще это сформулировал. ИМХО реализация дефолтных свойств как она есть в C# сделана не с той стороны. Вместо того, чтобы делать свойства с теневым полем, надо было сделать поля с автоматическим созданием свойства. Есть, к примеру, поле string name — автоматом создается свойство string Name с простейшей реализацией. Не нравится — напиши его сам. Ну и для полносты картины атрибут [Nonpropertable] запрещающий это либо для всего класса, либо для конкретного поля.

Нечто подобное сделано в языке Fan — http://fandev.org/doc/docLang/Fields.html
Можно писать по-всякому:
class Thing
{
  Int justField := 0

  Int overridedAccessors := 0
  {
    get { echo("get id"); return *overridedAccessors }
    set { echo("set id"); *overridedAccessors = val }
  }

  virtual Int virtualField := 0

  Int protectedSetter := 0 { protected set }

  protected Int oneMore := 0
  {
    private set 
    get { return doSomething(*oneMore) }  //getter will have protected visibility (field declaration)
  }
}
Re[3]: Зачем нужны поля в .Net?
От: Кирилл Осенков Украина
Дата: 29.10.09 08:52
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>А там можно заодно и делегаты приговорить.


Не, делегаты вещь очень полезная. Это ж по сути single-method interfaces, только вариантные и более мощные (duck typing). Надо правда добавить currying и приведение делегатов с одной сигнатурой. Ещё where T : delegate иногда не хватает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.